I'm having a very strange problem. I trying to do a WP8.0 application that uses a portable library. In this portable library, I'm using restsharp portable and everything was fine until instead of POSTs I started to do GETs. Going deeper, I found that the problem is in HttpClient, so I did a simple code just with HttpClient and found that using the same code in the following scenarios the results vary:
* in WP8+portable GET doesn't work, the call doesn't return but POST works fine
* in WP81 OK
I'm doing GET's to www.google.com and the POSTs to my own server. I am using the WP8.1 emulator for the tests.
Any idea?
Found the problem!
The code I was using to test was this:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://www.google.es/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("").Result;
if (response.IsSuccessStatusCode)
{
text = response.Content.ReadAsStringAsync().Result;
}
}
The problem is using Result in GetAsync. I don't know why but it worked fine if I changed to
await client.GetAsync("");
In my app, I have the code with await BUT the top level method wasn't async and I use .Result. The solution is not to use .Result when calling an async method (I don't know if it applies to every method or just HttpClient methods). The POST worked fine because they are in async methods.
Related
I'm developing an API for my android app.
I'm using the API for accessing MySql from android via Asp.Net.
Like this,
[Route("api/v1/getMethodExample")]
[HttpGet]
public int GetMethodExample(string parametre)
{
mySqlConnection = new MySqlConnection("");
mySqlConnection.Open();
...
//Do something with mysql
int value = mySqlConnection.get("myTable","4");//in example
mySqlConnection.Close();
return value;
}
In short, for every web API call, I'm connecting MySql, getting data and closing MySql.
Is this right way?
Yes. It's default behavior. In other way you will block context for other requests
I'm new to API testing. I need to integrate only one flow of API through Selenium as rest of GUI is already present.
I use API url on client browser, I get the result[json format]
I tried on SoapUI [REST] with the url, it gave the result[json format]
But when I try it on Selenium, I'm getting internal server error 500.
Please let me know the config changes that I need to take care.
string apiurl = "https://example.org/alfresco/s/org/alfresco/faceted/search?"
Here is the snippet of code i tried
URL url = new URL(apiurl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
String authString = "user:Password";
byte[] bytesEncoded = Base64.encodeBase64(authString.getBytes());
String authEncoded = new String("Basic "+bytesEncoded);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty("Authorization", authEncoded);
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent", "Apache-HttpClient/4.1.1 (java 1.5)");
conn.connect();
System.out.println(conn.getResponseCode());
I split the URL as
URL url = new URL(url);
conn.setRequestProperty("resource", "/alfresco/s/org/alfresco/faceted/search?");
conn.setRequestProperty("query", "%28Keywords%3A%27test%27%29");
conn.setRequestProperty("format", "json");
conn.setRequestProperty("resource", url+ "alfresco/s/org/alfresco/faceted/search?query=%28Keywords%3A%27test%27%29&count=10&format=json");
conn.setRequestProperty("Accept", "application/json");
Here I get 200 as response, but the response is on the example.org and not on the query appended.
Kindly let me know what is wrong that have done or need to add any information.
Maybe it is a little rude and not regarding current topic but I want to prevent you from doing a wrong job in future.
Using Selenium Webdriver for API testing you'll suffer a lot of pain.
Selenium Webdriver is not used for this porpuse.
Instead it there are a lot of good automation tools to test API.
One of them is Postman (chrome extension https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en)
Using this tool you'll get much more features and will be able to test any API with any requirenments.
I doubt you'll be able to do it with selenium Webdriver.
I recently got back into using GameMaker:Studio, and hoo boy have there been some massive updates since I last used it! In fact the last time I used it they only had Windows and HTML5 as export options...
Anyway, eager to try out some of the new stuff, I decided to take a shot at the native HTTP functions, since they looked very promising.
I did a test using http_post_string() to great effect, sending a JSON string to my server and getting a JSON string back. The returned string actually represented an object with a single property, "echo", which contained the HTTP request that had been made, just to see what GM:S was sending.
I didn't like that it sent Content-Type: application/x-www-form-urlencoded when it was quite clearly JSON, and I wanted the ability to set my own User Agent string so that the server could know which game was talking to it without having to pass an extra parameter.
So I re-created the same request using the lower-level http_request() function. Everything looked fine, so I tested it.
It crashed. Like, no error messages or anything, just a total crash and Windows had to force-close it.
So here I am with code that by all rights should work fine, but crashes when run...
///send_request(file,ds_map_data,callback_event_id)
var request = ds_map_create();
request[? "instance"] = id;
request[? "event"] = argument2;
if( !instance_exists(obj_ajax_callback)) {
instance_create(0,0,obj_ajax_callback);
}
var payload = json_encode(argument1);
var headers = ds_map_create();
headers[? "Content-Length"] = string_length(payload);
headers[? "Content-Type"] = "application/json";
headers[? "User-Agent"] = obj_ajax_callback.uastring;
var xhr = http_request("https://example.com/"+argument0,"POST",headers,payload);
with(obj_ajax_callback) {
active_callbacks[? xhr] = request;
}
ds_map_destroy(headers);
obj_ajax_callback is an object that maintains a ds_map of active requests, and in its HTTP event it listens for those requests' callbacks and reacts along the lines of with(request[? "instance"]) event_user(request[? "event"]) so that the calling object can handle the response. This hasn't changed from the fully working http_post_string() attempt.
Any idea what could be causing this crash?
The reason why this crashes is because you are sending the Content-Length header as a real instead of a string. If you change your line to
headers[? "Content-Length"] = string(string_length(payload));
It should work.
Some of requests to my Web Application return data not in HTML format (JSON).
How to handle this correctly?
I wrote the following page definition:
import com.fasterxml.jackson.databind.ObjectMapper
import geb.Page
class JsonResponse extends Page {
static url = null;
static at = {
true;
}
static ObjectMapper mapper = new ObjectMapper();
static content = {
readTree {
def jsonString = $("pre").text();
mapper.readTree(jsonString)
}
}
}
and it apparently works. But the question is, how correct it is?
It takes data from inside pre tag. This is because I saw this content inside driver.pageSource. Is this correct? May be it is driver-dependent?
I put null into url, since the page has different url depending on query. Is this correct?
Geb is not intended to be used to interact with HTTP API endpoints because it is built on top of WebDriver and hence expects to be used via a browser and on HTML pages.
If you want to test HTTP API endpoints then I would suggest using an http client to back your tests. There are many of them out in the wild, just to name a few in no particular order:
Apache HttpClient
RestAssured - this one is specifically for testing
Ratpack's TestHttpClient - again intended to be used for testing
OkHttp
Unirest
I was able to download the content of a PDF in a geb unit test using the Direct Download API. It is handy because it takes all the cookies from the session but does the download separately from the browser.
Example from that documentation:
Browser.drive {
go "http://myapp.com/login"
// login
username = "me"
password = "secret"
login().click()
// now find the pdf download link
def downloadLink = $("a.pdf-download-link")
// now get the pdf bytes
def bytes = downloadBytes(downloadLink.#href)
}
There are different methods for downloading different kinds of data. See the DownloadSupport API docs.
Because geb uses HttpsURLConnection to connect to an https endpoint instead of using the browser you can have problems with self-signed certificates. I solved that using this Stack Overflow answer.
I agree that Geb is not intended to be used to interact with HTTP API endpoints, but there are some contexts where this can be helpful, so add this snippet here for posterity:
when: 'I retrieve the JSON transaction list'
go '/transaction/transactionList'
then: 'Valid data is retrieved'
JsonSlurper jsonSlurper = new JsonSlurper()
Map<String, List> transactionList = jsonSlurper.parseText(driver.pageSource)
assert transactionList.categories.class == ArrayList
I'm porting a W8 application that uses httpclient library to connect to our server.
The main purpose of the application is to send images, but when I try to send pictures on my WP8 I got a 404 not found error (seems that Microsoft remapped to 404 a lot of errors), if i check the server logs, I can see that the server recevied about 1/4 of the image before failling. The same function seems to works fine in my W8 application (didn't tested on 3G), and works on WP8 if I use Wifi connection. I think that the problem could be the waiting time, so I tried to add Keep-Alive headers without success.
The current code I have is:
using (HttpClient httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromMinutes(10);
Stream streamW = new MemoryStream();
this.bSyncOK = await Send(streamW);
streamW.Seek(0, SeekOrigin.Begin);
HttpResponseMessage response = await httpClient.PostAsync(sUri, new StreamContent(streamW));
if (response.IsSuccessStatusCode)
{
Stream streamR = await response.Content.ReadAsStreamAsync();
this.bSyncOK = await Recv(streamR);
streamR.Dispose();
}
else
throw new HostNotFoundException();
}
The same server is used to upload pictures on other platforms like IOS and Android without problems.
I reproduced the problem using fiddler to simulate modem speeds. The problem is happening because Phone's HTTPWebRequest implementation will timeout the request whenever it exceeds around 60s. In the debugger I see them getting back ERROR_INTERNET_TIMEOUT from their native layer. The only workaround I can think of at the moment would be to send the file in smaller POSTs, assuming the server supports that.