2011-04-14 46 views
29

Estoy intentando iniciar una prueba de Selenium con una solicitud POST a mi aplicación.¿Hay alguna manera de comenzar con una solicitud POST usando Selenium?

En lugar de un simple open(/startpoint)

me gustaría hacer algo como open(/startpoint, stuff=foo,stuff2=bar)

¿Hay alguna manera de hacer eso?

Lo pregunto porque la página original que los mensajes a este punto de inicio depende de proveedores externos que son a menudo fuera de línea (entorno de desarrollo) y por lo tanto a menudo fallan demasiado pronto (y no son objeto de la prueba)


Creo que el envío de datos como GET también funcionaría. Prefiero usar un método POST.

Respuesta

13

Respuesta corta: No.

Pero es posible que pueda hacerlo con un poco de filthing. Si abre una página de prueba (con GET) y luego evalúa algunos JavaScript en esa página, debería poder replicar una solicitud POST. Consulte JavaScript post request like a form submit para ver cómo puede replicar una solicitud POST en JavaScript.

Espero que esto ayude.

5

Selenium IDE le permite ejecutar JavaScript usando storeEval comando. La solución mencionada anteriormente funciona bien si tiene una página de prueba (HTML, no XML) y solo necesita realizar una solicitud POST.

Si usted necesita para hacer de POST/PUT/DELETE o cualquier otra petición, entonces necesitará otro enfoque:

XMLHttpRequest!

El siguiente ejemplo se ha probado: todos los métodos (POST/PUT/DELETE) funcionan bien.

<!--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> 

Aclaración:

$ {requestParams} - parámetros que desea publicar (por ejemplo param1 = valor1 & param2 = valor3 & param1 = valor3) puede especificar tantos parámetros como sea necesario

$ {TargetURL} - camino a su script (si su página tiene ubicada en http://domain.com/application/update.php continuación targetUrl debe ser igual a /application/update.php)

$ {requestMethod} - tipo de método (en este caso particular, debe ser "POST", pero puede ser "PUT" o "Borrar" o cualquier otra)

5

selenio no ofrece actualmente API para esto, pero hay varias maneras de iniciar una solicitud HTTP en su prueba. Solo depende en qué idioma estás escribiendo.

En Java, por ejemplo, podría tener este aspecto:

// 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 
} 
4

Una forma muy práctica de hacer esto es crear una página de inicio ficticia para las pruebas de que no es más que una forma con el poste que tiene un único botón "Iniciar prueba" y un grupo de <input type="hidden" ... elementos con los datos de publicación apropiados.

Por ejemplo, puede crear una página SeleniumTestStart.html con estos contenidos:

<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> 

En este ejemplo, index.php es donde se encuentra su aplicación web normal.

El código de selenio al inicio de las pruebas incluiría entonces:

open /SeleniumTestStart.html 
clickAndWait starttestbutton 

Esto es muy similar a otras técnicas simuladas y las trozo utilizados en las pruebas automatizadas. Solo te estás burlando del punto de entrada a la aplicación web.

Es obvio que hay algunas limitaciones a este enfoque:

  1. datos no pueden ser demasiado grandes (por ejemplo, datos de imagen)
  2. de seguridad puede ser un problema por lo que necesita para asegurarse de que estos archivos de prueba no lo hacen terminar en el servidor de producción
  3. puede que tenga que hacer sus puntos de entrada con algo como php en lugar de hTML si es necesario configurar las cookies antes de la prueba de selenio se pone en marcha
  4. algunas aplicaciones web y comprueba la URL de referencia para asegurarse de que alguien ISN 'hackear la aplicación - en este ca SE Este enfoque probablemente no funcionará - usted puede ser capaz de aflojar esta comprobación en un entorno de desarrollo por lo que permite a los remitentes de los hosts de confianza (no auto, pero el anfitrión prueba real)

Por favor, considere la lectura de mi artículo sobre la Qualities of an Ideal Test

+1

Mucho más prueba que esas otras respuestas. – Smar

20

Si está utilizando Python selenium encuadernaciones, hoy en día, hay una extensión a selenium-selenium-requests:

Extiende clases WebDriver selenio para incluir la función de petición de los Reques su biblioteca, mientras hace todas las cookies necesarias y solicita el manejo de encabezados.

Ejemplo:

from seleniumrequests import Firefox 

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

esto parece prometedor, sin embargo, hay algunas preocupaciones, la primera es que si uso 'webdriver.request', se abre una pestaña nueva en lugar de la existente y se cierra cuando la solicitud termina, en segundo lugar, no representa la página prevista . Por ejemplo: digamos que envío una solicitud GET 'webdriver.request ('GET', 'http://example.com/some/path', data = {'a': 1, 'b' = 2}', el navegador se abre y muestra solo 'http: // example.com /' en lugar de 'http: //example.com/some/path? a = 1 & b = 2' – bawejakunal

+0

@bawejakunal, pero ¿qué ocurre con la solicitud posterior? – Volatil3

0

Bien, estoy de acuerdo con la @Mishkin Berteig - respuesta ágil entrenador. El uso del formulario es la forma más rápida de usar las funciones POST.

De todos modos, veo alguna mención sobre javascript, pero no hay código. Lo tengo para mis propias necesidades, que incluye jquery para POST más otros más.

Básicamente, utilizando el driver.execute_script() puede enviar cualquier javascript, incluidas las consultas Ajax.

#/usr/local/env/python 
# -*- coding: utf8 -*- 
# proxy is used to inspect data involved on the request without so much code. 
# using a basic http written in python. u can found it there: http://voorloopnul.com/blog/a-python-proxy-in-less-than-100-lines-of-code/ 

import selenium 
from selenium import webdriver 
import requests 
from selenium.webdriver.common.proxy import Proxy, ProxyType 

jquery = open("jquery.min.js", "r").read() 
#print jquery 

proxy = Proxy() 
proxy.proxy_type = ProxyType.MANUAL 
proxy.http_proxy = "127.0.0.1:3128" 
proxy.socks_proxy = "127.0.0.1:3128" 
proxy.ssl_proxy = "127.0.0.1:3128" 

capabilities = webdriver.DesiredCapabilities.PHANTOMJS 
proxy.add_to_capabilities(capabilities) 

driver = webdriver.PhantomJS(desired_capabilities=capabilities) 

driver.get("http://httpbin.org") 
driver.execute_script(jquery) # ensure we have jquery 

ajax_query = ''' 
      $.post("post", { 
       "a" : "%s", 
       "b" : "%s" 
      }); 
      ''' % (1,2) 

ajax_query = ajax_query.replace(" ", "").replace("\n", "") 
print ajax_query 

result = driver.execute_script("return " + ajax_query) 
#print result 

#print driver.page_source 

driver.close() 

# this retuns that from the proxy, and is OK 
''' 
POST http://httpbin.org/post HTTP/1.1 
Accept: */* 
Referer: http://httpbin.org/ 
Origin: http://httpbin.org 
X-Requested-With: XMLHttpRequest 
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.0.0 Safari/538.1 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Content-Length: 7 
Cookie: _ga=GAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; _gat=1 
Connection: Keep-Alive 
Accept-Encoding: gzip, deflate 
Accept-Language: es-ES,en,* 
Host: httpbin.org 


None 
a=1&b=2 <<---- that is OK, is the data contained into the POST 
None 
''' 
Cuestiones relacionadas