有没有办法从使用Selenium的POST请求开始?

Rom*_*net 46 selenium

我正在尝试使用对我的应用程序的POST请求启动Selenium测试.

而不是一个简单的 open(/startpoint)

我想做点什么 open(/startpoint, stuff=foo,stuff2=bar)

有没有办法做到这一点?

我问这个是因为发布到这个起始点的原始页面取决于经常脱机的外部提供程序(开发环境),因此通常会过早失败(并且不是测试的主题)


我想发送数据作为GET也会起作用.我更喜欢使用POST方法.

ale*_*cxe 33

如果你正在使用Python selenium绑定,现在有一个扩展名selenium- selenium-requests:

扩展Selenium WebDriver类以包含来自Requests库的请求函数,同时执行所有需要的cookie和请求标头处理.

例:

from seleniumrequests import Firefox

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


Tne*_*nem 15

简答:不.

但你可能会做一些事情.如果您打开一个测试页面(使用GET),然后评估该页面上的一些JavaScript,您应该能够复制POST请求.请参阅JavaScript post请求,如表单提交,以了解如何在JavaScript中复制POST请求.

希望这可以帮助.


小智 12

我曾经driver.execute_script()将html表单注入到页面中,然后提交。它看起来像这样:

def post(path, params):
    driver.execute_script("""
    function post(path, params, method='post') {
        const form = document.createElement('form');
        form.method = method;
        form.action = path;
    
        for (const key in params) {
            if (params.hasOwnProperty(key)) {
            const hiddenField = document.createElement('input');
            hiddenField.type = 'hidden';
            hiddenField.name = key;
            hiddenField.value = params[key];
    
            form.appendChild(hiddenField);
        }
        }
    
        document.body.appendChild(form);
        form.submit();
    }
    
    post(arguments[1], arguments[0]);
    """, params, path)

# example 
post(path='/submit', params={'name': 'joe'})
Run Code Online (Sandbox Code Playgroud)

如果您愿意,您可以将函数添加到其中\selenium\webdriver\chrome\webdriver.py,然后在代码中使用它driver.post()


小智 8

一个非常实用的方法是为您的测试创建一个虚拟起始页面,它只是一个带有POST的表单,它有一个"开始测试"按钮和一堆<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>
Run Code Online (Sandbox Code Playgroud)

在此示例中,index.php是您的普通Web应用程序所在的位置.

测试开始时的Selenium代码将包括:

open /SeleniumTestStart.html
clickAndWait starttestbutton
Run Code Online (Sandbox Code Playgroud)

这与自动化测试中使用的其他模拟和存根技术非常相似.您只是在嘲笑Web应用程序的入口点.

显然这种方法有一些限制:

  1. 数据不能太大(例如图像数据)
  2. 安全性可能是一个问题,因此您需要确保这些测试文件不会在生产服务器上结束
  3. 如果你需要在Selenium测试开始之前设置cookie,你可能需要使用像php而不是html这样的入口点
  4. 一些网络应用程序检查引用来确保有人不是黑客攻击应用程序 - 在这种情况下,这种方法可能无法正常工作 - 您可以在开发环境中放松此检查,以便它允许来自可信主机的引用者(不是自我) ,但实际测试主机)

请考虑阅读我关于理想测试质量的文章


Ale*_*exG 5

Selenium IDE允许您使用storeEval命令运行Javascript.如果您有测试页(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>
Run Code Online (Sandbox Code Playgroud)

澄清:

$ { requestParams } - 您要发布的参数(例如param1 = value1¶m2 = value3¶m1 = value3)您可以根据需要指定任意数量的参数

$ { targetUrl } - 脚本的路径(如果您的页面位于http://domain.com/application/update.php,则targetUrl应该等于/application/update.php)

$ { requestMethod } - 方法类型(在这种特殊情况下它应该是"POST"但可以是"PUT"或"DELETE"或任何其他)


m3n*_*nda 5

嗯,我同意@Mishkin Berteig - 敏捷教练的回答。使用表单是使用 POST 功能的快捷方式。

不管怎样,我看到一些关于 JavaScript 的提及,但没有代码。我有它来满足我自己的需求,其中包括用于轻松 POST 的 jQuery 以及其他功能。

基本上,使用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
'''
Run Code Online (Sandbox Code Playgroud)