在 Selenium 中发出 POST 请求而不填写表单?

问题描述 投票:0回答:3

我有一个应用程序 A 应该处理使用 POST 方法提交的表单。发起请求的实际表单位于完全独立的应用程序 B 中。我正在使用 Selenium 测试应用程序 A,并且我喜欢编写一个用于表单提交处理的测试用例。

如何做到这一点?这可以在 Selenium 中完成吗?应用程序 A 没有可以发起此请求的表单。

注意,请求必须使用POST,否则我可以直接使用WebDriver.get(url)方法。

forms testing post selenium request
3个回答
16
投票

使用 selenium,您可以执行任意 Javascript,包括 以编程方式提交表单

使用 Selenium Java 执行最简单的 JS:

if (driver instanceof JavascriptExecutor) {
    System.out.println(((JavascriptExecutor) driver).executeScript("prompt('enter text...');"));
}

并且使用 Javascript,您可以创建 POST 请求,设置所需的参数和 HTTP 标头,然后提交。

// Javascript example of a POST request
var xhr = new XMLHttpRequest();
// setting 3rd arg to false forces *synchronous* mode
xhr.open('POST', 'http://httpbin.org/post', false);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('login=test&password=test');
alert(xhr.response);

在现代前沿浏览器中,您还可以使用

fetch()

如果您需要将响应文本传递给 selenium,则使用

alert(this.responseText)
return this.responseText
代替
return this.response
,并将
execute_script
(或
execute_async_script
)的结果分配给变量)(如果使用Python)。对于 Java,对应的是
executeScript()
executeAsyncScript()

这是 python 的完整示例:

from selenium import webdriver

driver = webdriver.Chrome()

js = '''var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://httpbin.org/post', false);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

xhr.send('login=test&password=test');
return xhr.response;'''

result = driver.execute_script(js);

result
将包含 JavaScript 的返回值,前提是 js 代码是同步的。将
false
设置为
xhr.open(..)
的第三个参数会强制请求同步。将第三个参数设置为
true
或省略它将使请求异步。

❗️ 如果您正在调用 asynchronous js 代码,请确保使用

execute_script
而不是
execute_async_script
,否则调用将不会返回任何内容!

注意:如果您需要将字符串参数传递给 javascript,请确保始终使用

json.dumps(myString)
对它们进行转义,否则当字符串包含单引号或双引号或其他棘手字符时,您的 js 将会中断。


3
投票

我认为使用 Selenium 是不可能的。没有办法使用 Web 浏览器从无到有地创建 POST 请求,而 Selenium 是通过操纵 Web 浏览器来工作的。我建议您使用 HTTP 库来发送 POST 请求,并将其与 Selenium 测试一起运行。 (您使用什么语言/测试框架?)


1
投票

我发现的最简单的方法是创建一个中间页面,仅用于提交 POST 请求。让selenium打开页面,提交表单,然后获取最终页面的源码。

from selenium import webdriver
html='<html><head><title>test</title></head><body><form action="yoursite.com/postlocation" method="post" id="formid"><input type="hidden" name="firstName" id="firstName" value="Bob"><input type="hidden" name="lastName" id="lastName" value="Boberson"><input type="submit" id="inputbox"></form></body></html>'
htmlfile='/tmp/temp.html'
    try:
        with open(htmlfile, "w") as text_file:
            text_file.write(html)
    except:
        print('Unable to create temporary HTML file')
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.get('file://'+htmlfile)
driver.find_element_by_id('inputbox').click();
#wait for form to submit and finish loading page
wait = WebDriverWait(driver, 30)
response=driver.page_source
© www.soinside.com 2019 - 2024. All rights reserved.