15

I have an application A that should handle a form submit made with POST method. The actual form, that initiates the request, is in totally separate application B. I am testing application A using Selenium, and I like to write a test case for form submit handling.

How to do this? Can this be done in Selenium at all? Application A does not have a form that can initiate this request.

Note, that the request must use POST, otherwise I could just use WebDriver.get(url) method.

4

3 回答 3

13

使用 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();
// false as 3rd argument will forces synchronous processing
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.responseTextor并将(or )return this.response的结果分配给变量(如果使用 python)。对于将或相应的java。execute_scriptexecute_async_scriptexecuteScript()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或省略它将使请求异步。

❗️ 如果您正在调用异步js 代码,请确保execute_script您使用而不是使用execute_async_script,否则该调用将不会返回任何内容!

注意:如果您需要将字符串参数传递给 javascript,请确保始终使用转义它们json.dumps(myString),否则当字符串包含单引号或双引号或其他棘手字符时,您的 js 将中断。

于 2017-01-22T19:33:37.880 回答
3

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

于 2012-05-08T08:09:00.820 回答
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
于 2020-05-31T01:39:46.493 回答