Is there any way to start with a POST request using Selenium?

I'm trying to start a Selenium test with a POST request to my application.

Instead of a simple open(/startpoint)

I would like to do something like open(/startpoint, stuff=foo,stuff2=bar)

Is there any way to do that?

I'm asking this because the original page which posts to this start point depends on external providers that are often offline (development environment) and so will often fail too early (and are not the subject of the test)


I guess sending data as GET would work too. I would just prefer using a POST method.


If you are using Python selenium bindings, nowadays, there is an extension to selenium - selenium-requests:

Extends Selenium WebDriver classes to include the request function from the Requests library, while doing all the needed cookie and request headers handling.

Example:

from seleniumrequests import Firefox

webdriver = Firefox()
response = webdriver.request('POST', 'url here', data={"param1": "value1"})
print(response)

Short answer: No.

But you might be able to do it with a bit of filthing. If you open up a test page (with GET) then evaluate some JavaScript on that page you should be able to replicate a POST request. See JavaScript post request like a form submit to see how you can replicate a POST request in JavaScript.

Hope this helps.


One very practical way to do this is to create a dummy start page for your tests that is simply a form with POST that has a single "start test" button and a bunch of <input type="hidden"... elements with the appropriate post data.

For example you might create a SeleniumTestStart.html page with these contents:

<body>
  <form action="/index.php" method="post">
    <input id="starttestbutton" type="submit" value="starttest"/>
    <input type="hidden" name="stageid" value="stage-you-need-your-test-to-start-at"/>
  </form>
</body>

In this example, index.php is where your normal web app is located.

The Selenium code at the start of your tests would then include:

open /SeleniumTestStart.html
clickAndWait starttestbutton

This is very similar to other mock and stub techniques used in automated testing. You are just mocking the entry point to the web app.

Obviously there are some limitations to this approach:

  1. data cannot be too large (e.g. image data)
  2. security might be an issue so you need to make sure that these test files don't end up on your production server
  3. you may need to make your entry points with something like php instead of html if you need to set cookies before the Selenium test gets going
  4. some web apps check the referrer to make sure someone isn't hacking the app - in this case this approach probably won't work - you may be able to loosen this checking in a dev environment so it allows referrers from trusted hosts (not self, but the actual test host)

Please consider reading my article about the Qualities of an Ideal Test


Selenium IDE allows you to run Javascript using storeEval command. Mentioned above solution works fine if you have test page (HTML, not XML) and you need to perform only POST request.

If you need to make POST/PUT/DELETE or any other request then you will need another approach:

XMLHttpRequest!

Example listed below has been tested - all methods (POST/PUT/DELETE) work just fine.

<!--variables-->
<tr>
    <td>store</td>
    <td>/your/target/script.php</td>
    <td>targetUrl</td>
</tr>
<tr>
    <td>store</td>
    <td>user=user1&amp;password</td>
    <td>requestParams</td>
</tr>
<tr>
    <td>store</td>
    <td>POST</td>
    <td>requestMethod</td>
</tr>
<!--scenario-->
<tr>
    <td>storeEval</td>
    <td>window.location.host</td>
    <td>host</td>
</tr>
<tr>
    <td>store</td>
    <td>http://${host}</td>
    <td>baseUrl</td>
</tr>
<tr>
    <td>store</td>
    <td>${baseUrl}${targetUrl}</td>
    <td>absoluteUrl</td>
</tr>
<tr>
    <td>store</td>
    <td>${absoluteUrl}?${requestParams}</td>
    <td>requestUrl</td>
</tr>
<tr>
    <td>storeEval</td>
    <td>var method=storedVars['requestMethod']; var url = storedVars['requestUrl']; loadXMLDoc(url, method); function loadXMLDoc(url, method) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4) { if(xmlhttp.status==200) { alert(&quot;Results = &quot; + xmlhttp.responseText);} else { alert(&quot;Error!&quot;+ xmlhttp.responseText); }}};&nbsp;&nbsp;xmlhttp.open(method,url,true); xmlhttp.send(); }</td>
    <td></td>
</tr>

Clarification:

${requestParams} - parameters you would like to post (e.g. param1=value1&param2=value3&param1=value3) you may specify as many parameters as you need

${targetUrl} - path to your script (if your have page located at http://domain.com/application/update.php then targetUrl should be equal to /application/update.php)

${requestMethod} - method type (in this particular case it should be "POST" but can be "PUT" or "DELETE" or any other)


Selenium doesn't currently offer API for this, but there are several ways to initiate an HTTP request in your test. It just depends what language you are writing in.

In Java for example, it might look like this:

// setup the request
String request = "startpoint?stuff1=foo&stuff2=bar";
URL url = new URL(request);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");

// get a response - maybe "success" or "true", XML or JSON etc.
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuffer response = new StringBuffer();
while ((line = bufferedReader.readLine()) != null) {
    response.append(line);
    response.append('\r');
}
bufferedReader.close();

// continue with test
if (response.toString().equals("expected response"){
    // do selenium
}