我的页面包含一个表单,用户可以在其中输入其姓名:
<form method="post" onsubmit="nameSubmitted()">
<input id="nameField" name="username" type="text" autofocus>
<input type="hidden" name="form" value="username">
<input id="nameSubmitButton" type="submit" value="OK">
</form>
在赛普拉斯,我这样做:
cy.visit('http://localhost:8080/my-page-name.html');
cy.get('[id="nameField"]')
.type(my-test-username);
cy.get('[id="nameSubmitButton"]')
.click();
预期的行为是服务器将给定的用户名与当前会话相关联,并且用户停留在同一页面上,其中nameSubmitted()
函数显示并隐藏了一些DOM元素。当使用Firefox,Chrome,Opera或Brave的常规实例进行手动测试时,此方法可以很好地工作,但是当Cypress在Electron或Firefox中尝试相同的操作时,该方法将失败(我无法将其他浏览器添加到Cypress,但这是一个单独的问题)。
该服务器是我编写的第一台HTTP服务器,因此我不能100%确信其行为是正确的,但是我找不到任何错误。它是使用com.sun.net.httpserver.HttpServer
和相关类用Java编写的,我已经尝试了两种不同的POST请求响应:
204
没有内容在com.sun.net.httpserver.HttpExchange
实例上,我呼叫:
aHttpExchange.sendResponseHeaders(204, -1);
aHttpExchange.getResponseBody().close();
这会导致赛普拉斯在等待页面加载时卡住,直到60秒后超时。实际上,没有什么新内容可以加载,并且Cypress浏览器实例右侧的页面图像显示该页面正确显示(nameSubmitted()
函数已正确修改了DOM)。我还在服务器上看到POST请求成功并且设置了用户名。
200
OK 只是一个猜测,我尝试设置
aHttpExchange.sendResponseHeaders(200, 0);
,并在关闭OutputStream之前向其发送空字符串。这会导致赛普拉斯(以及处于非测试模式的普通浏览器)将这个空字符串设置为页面内容,所以这样做没有好处。
根据http spec:
由POST方法执行的操作可能不会导致可以由URI标识的资源。在这种情况下,适当的响应状态是200(确定)或204(无内容),具体取决于响应是否包括描述结果的实体。
因此,似乎我的服务器应该对响应(1)做正确的事情。
有人知道为什么会超时吗?
答案 0 :(得分:0)
我在https://gitter.im/cypress-io/cypress的用户jorrit-wehelp
的帮助下解决了这个问题。
现在通过在每个表单元素中放置onsubmit="return false;"
来禁用默认表单提交机制:
<form id="nameForm" onsubmit="return false;">
<input id="nameField" name="username" type="text" autofocus>
<button id="nameSubmitButton" onclick="submitName()">OK</button>
</form>
类型为Submit的输入已被按钮替换,其onclick
方法检索输入的文本,并通过调用fetch
将其发送:
const username = document.getElementById('nameField').value;
fetch('username', { method: 'POST', body: 'username=' + username })
.catch(err => console.error(err));
服务器响应没有改变,但是我现在控制浏览器在获得响应时的行为。另外,我现在可以直接发布到username
,而不用使用隐藏的表单元素来保存表单的名称,并在服务器端读取隐藏元素的内容以分派请求。