Will Roku WebDriver setup work with my Java framework - selenium

I know Roku Webdriver repository comes with python and Postman sample scripts but I was wondering if I could use my Java scripts - not javascript - to connect to go and automate. If so, does anyone have any examples how to setup the driver in Java?
https://developer.roku.com/en-ca/docs/developer-program/dev-tools/automated-channel-testing/web-driver.md

You can give a try Rokuality.
From README: it is one of the first projects to provide support for the Roku WebDriver API.
If it is not up-to-date, you can take a core as a basis for your test framework

My recommendation would be to download the solution that Roku provides, read the API documentation, use their sample solution for Python, JavaScript and/or Postman to get familiar with the technology, then write your own solution for Java.
The core of the Roku WebDriver solution is an HTTP server which sends ECP commands (remote control primarily) and is able to query the XML source of the Roku channel under test to responses in JSON wire protocol format. Using the documentation and the sample libraries, it will be a straight forward task to write a class for your Java solution which can send GET and POST requests to the WebDriver HTTP server. You can use the Roku provided Go language solution to compile binaries for the HTTP server on the platform(s) you want to support (Mac/Linux/Windows, etc.) and then include the binaries in your solution. You will also want to write a class to to launch and manage the state of the HTTP server and likely extend the solution further to do other things like parsing the responses of the JSON responses from the server, capturing logs from devices and saving screenshots.
Though I have not used Java with Roku WebDriver, I started working with Roku WebDriver shortly after it was released. We wanted to use JavaScript and at the time, Roku had not yet released their JavaScript library, so I wrote one for the project I am working on. It was a pretty straight forward task with Roku's API documentation and Robot Framework library to reference. I see no reason you couldn't do the same in Java, C# or comparable languages.
Note: another user pointed out the Rokuality solution. While it certainly wouldn't hurt to review their implementation to learn from it, it would seem to have a lot of complexity which you don't likely need. A lot of the solution seems designed to interact with the Rokuality cloud service offering and at this point their domain doesn't go anywhere, so I'm not sure they are still up and running.

I figured it out. If anyone is interested in automating it in Java, this code will work as a starting point. Make sure to connect to Go server first. The steps are on https://developer.roku.com/en-ca/docs/developer-program/dev-tools/automated-channel-testing/automated-testing-overview.md . Dont forget to update bash or zshrc with
export GOPATH=/Users/$USER/eclipse-workspace/automated-channel-testing-master
Once the server is running, run the code. Make sure you add your own IP. Thats located in settings on the Roku device. Also add a close method so that you wont get any errors that the "session is already running". If you do get that, just reset the server.
Again this is just a starting point - use the APIs in https://developer.roku.com/en-ca/docs/developer-program/dev-tools/automated-channel-testing/web-driver.md to really start automating.
String ip ;
JSONObject json;
String cookie;
public RokuDriver(String IP) {
this.ip = IP;
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
RequestBody body = RequestBody.create("{\n\t\"ip\": \""+ip+"\"\n}", MediaType.parse("application/json"));
Request request = new Request.Builder()
.url("http://localhost:9000/v1/session")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
try {
Response response = client.newCall(request).execute();
JSONObject jsonBody = new
JSONObject(response.body().string());
cookie = jsonBody.getString("sessionId");
System.out.println(jsonBody.toString(4));
response.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
close();
}
}
public void down() {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create("{\n\t\"button\": \"down\"\n}", MediaType.parse("application/json"));
Request request = new Request.Builder()
.url("http://localhost:9000/v1/session/"+cookie+"/press")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
try {
Response response = client.newCall(request).execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
POM:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-urlconnection</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>

Related

Logging HTTP requests and responses in quarkus resteasy

I am running into a problem with calling a REST endpoint on a server, using a REST client in Quarkus, built with the org.eclipse.microprofile.rest.client.RestClientBuilder. I would very much like to debug the service, by writing the HTTP requests and responses to the log, so I might see what is actually being sent to the server. The hunt for a guide for that particular issue has eluded me however.
I managed to build a logging filter but that only logs out the URL and the Entitys toString value, which is not at all the same as the HTTP request and response being sent.
Help me by pointing me to a solution to log the actual HTTP request and response.
You can try to enable the logging for all the traffic including wire or just some components, here in the logging configuration guide you can find how enable just some components logging.
Add this to your application.properties and you should be able to see some logging information quarkus.log.category."org.apache.http".level=DEBUG
If you need to log everything you can always put quarkus in debug level ALL, and the pick the components you need to constraint the logging, whit this you see all the traces at wire level.
You can also enable the http access log with this guide
Good luck.
If you are using resteasy reactive you can turn on logging with:
quarkus.rest-client.logging.scope=request-response
quarkus.rest-client.logging.body-limit=1024
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
Check this: https://quarkus.io/guides/resteasy-reactive#the-jax-rs-way
Simply implement that class and you will start logging. Like this:
#Provider
class LoggingFilter implements ContainerRequestFilter,
ContainerResponseFilter {
/* Useful stuff for later development purposes.
#Context
UriInfo info;
#Context
HttpServerRequest request;
*/
#Override
public void filter(ContainerRequestContext requestContext) {
Log.info(requestContext);
}
#Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
Log.info(responseContext);
}
}
Then you may use UriInfo, HttpServerRequest and ContainerRequestContext to get any data you want and add to your custom log.

NTLM authentication for REST api in Karate framework

Have anyone tried NTLM authentication implemented in Karate framework which i could refer? I get 401 authorization issue while I try building a test and pass header argument.
#BeforeClass
public static void before() {
System.setProperty("http.auth.ntlm.domain", "***");
System.setProperty("jcifs.smb.client.domain", "***");
System.setProperty("jcifs.smb.client.username", "***");
System.setProperty("jcifs.smb.client.password", "***");
System.setProperty("java.protocol.handler.pkgs", "jcifs");
}
Unfortunately NTLM support is not yet implemented in Karate. There is an open feature request: https://github.com/intuit/karate/issues/372 We'll need you or someone to contribute this from the open-source community.
Meanwhile you should be able to work-around this by using a Java library or custom Java code that does the necessary authentication. Refer to the Java inter-op section of the Karate documentation: https://github.com/intuit/karate#calling-java
EDIT: also see https://stackoverflow.com/a/51150286/143475
EDIT - you can use curl ! https://stackoverflow.com/a/64352676/143475

Can Spring Cloud Sleuth trace HTTP calls made through Async RestTemplate

I am trying to trace HTTP calls made through Async RestTemplate from a Spring Boot Application.
I have a ZipKin instance running locally to which the microservices in question point to.
I could see spans recorded at every service in ZipKin UI, however I am not able to see the trace covering all the spans.
With RestTemplate the trace is recorded as normal. i.e. I am able to see end-to-end via the UI.
Any pointers will help,
Thanks in advance.
I'm not sure this is what you are expecting, you can add this dependancy in pom.xml if you are using maven:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
and a AlwaysSampler #Bean in your SpringBootApplication class
#Bean
public AlwaysSampler defaultSampler(){
return new AlwaysSampler();
}
This will help you to sample your inputs in zipkin all time.

IIS 7 Serves GET request correctly to browser but throws timeout exception for API request

I am running a very simple Web application (Asp.Net MVC3) on Win 7 IIS.
I have a very simple HTTP GET API which returns hello world.
Calling:
http://localhost/helloworld
Returns:
Hello World!
This works perfectly over a browser.
But when I write an app which tries to pull this URL using a webclient, I get the following error:
{"Unable to read data from the transport connection: The connection was closed."}
My Code is as follows
WebClient web = new WebClient();
var response = web.DownloadString("http://localhost/helloworld");
My IIS Settings are as follows
What should I be looking at? I have been at this for hours and I have run out of options to try! Any help will be really appreciated!
Thanks.
I suspect it's because WebClient does not send some of the HTTP headers:
A WebClient instance does not send optional HTTP headers by default. If your request requires an optional header, you must add the header to the Headers collection. For example, to retain queries in the response, you must add a user-agent header. Also, servers may return 500 (Internal Server Error) if the user agent header is missing. http://msdn.microsoft.com/en-us/library/system.net.webclient(v=vs.80).aspx
Try using HttpWebRequest instead. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx
I finally figured out what the issue was and instead of it being an IIS specific issue - which I was leaning towards, it turned out to be an issue with the code that I wrote.
Adding details here incase someone else runs into a similar problem.
I had the following method in my code which I was using to send the response of the request as a JSON object.
private void sendJsonResult(string result) {
Response.StatusCode = 200;
Response.Headers.Add("Content-Type", "application/json; charset=utf-8");
Response.Flush();
Response.Write(result);
Response.End();
Response.Close(); // <-- This is the problem statement
}
On digging around a bit, I found out that we should not be doing a Response.Close().
A better explanation of this is here.
Once I removed that line, it started working perfectly - both in my consuming app as well as the web browser, etc.
If you will read the link above, you will clearly understand why we should not be using a Response.Close() - so I will not go into that description. Learnt a new thing today.

How to host Web API in Windows Service

I have several resources that I'd like to expose using the WCF Web API. I've investigated the Web API using a Web host but our services all run as Windows Services in production so it's time for me to put the tests aside and verify that everything will work as we need it. I've looked as the sample app here: http://webapicontrib.codeplex.com/SourceControl/changeset/view/2d771a4d6f6f#Samples%2fSelfHosted%2fserver%2fProgram.cs but this does not work with the current version (preview 5) because the HttpConfigurableServiceHost class is not accessible from our code.
One of the most appealing aspects of the Web API is the simple startup using MapServiceRoute and the new WebApiConfiguration. I don't see, however, a way to define the base url and port for the services. Obviously, hosting the service in IIS eliminates this because we configure this information in IIS. How can I accomplish this when hosting in a Windows Service?
It's actually pretty simple. In a nutshell you need to instantiate HttpSelfHostServer and HttpSelfHostConfiguration and then call server.OpenAsync().
public void Start()
{
_server.OpenAsync();
}
public void Stop()
{
_server.CloseAsync().Wait();
_server.Dispose();
}
For an example on how to do this using Windows service project template and/or Topshelf library see my blog post: http://www.piotrwalat.net/hosting-web-api-in-windows-service/
The latest version just uses HttpServiceHost. http://webapicontrib.codeplex.com/SourceControl/changeset/view/ddc499585751#Samples%2fSelfHosted%2fserver%2fProgram.cs
Ping me on twitter if you continue to have problems.
This is the basic code using a console app. A Windows Service uses the same basic approach except you use the start and stop methods to start and stop the service and don't need to block.
static void Main(string[] args)
{
var host = new HttpServiceHost(typeof(PeopleService), "http://localhost:8080/people");
host.Open();
foreach (var ep in host.Description.Endpoints)
{
Console.WriteLine("Using {0} at {1}", ep.Binding.Name, ep.Address);
}
Console.ReadLine();
host.Close();
}
See this blog post.