我有一个应用程序 A 应该处理使用 POST 方法提交的表单。发起请求的实际表单位于完全独立的应用程序 B 中。我正在使用 Selenium 测试应用程序 A,并且我喜欢编写一个用于表单提交处理的测试用例。
如何做到这一点?这可以在 Selenium 中完成吗?应用程序 A 没有可以发起此请求的表单。
注意,请求必须使用POST,否则我可以直接使用WebDriver.get(url)方法。
使用 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,请确保始终使用
对它们进行转义,否则当字符串包含单引号或双引号或其他棘手字符时,您的 js 将会中断。json.dumps(myString)
我认为使用 Selenium 是不可能的。没有办法使用 Web 浏览器从无到有地创建 POST 请求,而 Selenium 是通过操纵 Web 浏览器来工作的。我建议您使用 HTTP 库来发送 POST 请求,并将其与 Selenium 测试一起运行。 (您使用什么语言/测试框架?)
我发现的最简单的方法是创建一个中间页面,仅用于提交 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