Есть ли способ начать с запроса POST, используя Selenium? - PullRequest
42 голосов
/ 14 апреля 2011

Я пытаюсь запустить тест Selenium с запросом POST к моему приложению.

Вместо простого open(/startpoint)

Я хотел бы сделать что-то вроде open(/startpoint, stuff=foo,stuff2=bar)

Есть ли способ сделать это?

Я спрашиваю об этом, потому что исходная страница, которая публикует данные в этой начальной точке, зависит от внешних провайдеров, которые часто находятся в автономном режиме (среда разработки) и поэтому часто выходят из строя слишком рано (и не являются предметом теста)


Я думаю, отправка данных как GET тоже будет работать. Я бы просто предпочел использовать метод POST.

Ответы [ 6 ]

32 голосов
/ 08 июля 2015

Если вы используете привязки Python selenium, в настоящее время существует расширение к selenium - selenium-requests:

Расширяет классы Selenium WebDriver для включения функции запроса из библиотеки запросов, делая все необходимые файлы cookie и обработка заголовков запроса.

Пример:

from seleniumrequests import Firefox

webdriver = Firefox()
response = webdriver.request('POST', 'url here', data={"param1": "value1"})
print(response)
14 голосов
/ 14 апреля 2011

Краткий ответ: Нет.

Но вы могли бы сделать это с небольшим количеством грязи. Если вы откроете тестовую страницу (с помощью GET), тогда оцените некоторый JavaScript на этой странице, и вы сможете повторить запрос POST. См. Запрос публикации JavaScript, например отправку формы , чтобы увидеть, как можно реплицировать запрос POST в JavaScript.

Надеюсь, это поможет.

8 голосов
/ 25 декабря 2013

Один очень практичный способ сделать это - создать фиктивную стартовую страницу для ваших тестов, которая представляет собой просто форму с POST, в которой есть одна кнопка «start test» и набор элементов <input type="hidden" ... с соответствующими опубликовать данные.

Например, вы можете создать страницу SeleniumTestStart.html с таким содержанием:

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

В этом примере index.php - это место, где находится ваше обычное веб-приложение.

Код Selenium в начале ваших тестов будет включать:

open /SeleniumTestStart.html
clickAndWait starttestbutton

Это очень похоже на другие методы имитации и заглушки, используемые в автоматическом тестировании. Вы просто издеваетесь над точкой входа в веб-приложение.

Очевидно, что у этого подхода есть некоторые ограничения:

  1. данные не могут быть слишком большими (например, данные изображения)
  2. безопасность может быть проблемой, поэтому вам нужно убедиться, что эти тестовые файлы не попадают на ваш рабочий сервер
  3. вам может понадобиться сделать точки входа с помощью php вместо html, если вам нужно установить cookie-файлы до начала теста Selenium
  4. некоторые веб-приложения проверяют реферер, чтобы удостовериться, что кто-то не взломал приложение - в этом случае этот подход, вероятно, не сработает - вы можете ослабить эту проверку в среде разработчика, поэтому он позволяет ссылкам с доверенных хостов (не сам, а фактический тестовый хост)

Пожалуйста, прочитайте мою статью о Качествах идеального теста

5 голосов
/ 09 декабря 2012

Selenium IDE позволяет запускать Javascript с помощью команды storeEval . Упомянутое выше решение отлично работает, если у вас есть тестовая страница (HTML, а не XML), и вам нужно выполнить только POST-запрос.

Если вам нужно сделать POST / PUT / DELETE или любой другой запрос, вам понадобится другой подход:

XMLHttpRequest !

Пример, приведенный ниже, был протестирован - все методы (POST / PUT / DELETE) работают нормально.

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

Пояснение:

$ { requestParams } - параметры, которые вы хотите опубликовать (например, param1 = value1 & param2 = value3 & param1 = value3) Вы можете указать столько параметров, сколько вам нужно

$ { targetUrl } - путь к вашему сценарию (если ваша страница расположена по адресу http://domain.com/application/update.php, то targetUrl должен быть равен /application/update.php)

$ { requestMethod } - тип метода (в данном конкретном случае это должен быть «POST», но может быть «PUT» или «DELETE» или любой другой)

4 голосов
/ 23 августа 2013

В настоящее время Selenium не предлагает API для этого, но есть несколько способов инициировать HTTP-запрос в вашем тесте.Это зависит только от того, на каком языке вы пишете.

Например, в Java это может выглядеть так:

// 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
}
2 голосов
/ 17 января 2017

Ну, я согласен с ответом @Mishkin Berteig - Agile Coach.Использование формы - это быстрый способ использовать функции POST.

В любом случае, я вижу некоторые упоминания о javascript, но без кода.У меня есть это для моих собственных нужд, включая jquery для простого POST и другие.

По сути, используя driver.execute_script(), вы можете отправлять любой javascript, включая запросы 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
'''
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...