赛普拉斯发出POST请求后超时

时间:2020-04-27 17:18:54

标签: javascript java http cypress end-to-end

我的页面包含一个表单,用户可以在其中输入其姓名:

<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请求响应:

  1. 204没有内容

com.sun.net.httpserver.HttpExchange实例上,我呼叫:

aHttpExchange.sendResponseHeaders(204, -1);
aHttpExchange.getResponseBody().close();

这会导致赛普拉斯在等待页面加载时卡住,直到60秒后超时。实际上,没有什么新内容可以加载,并且Cypress浏览器实例右侧的页面图像显示该页面正确显示(nameSubmitted()函数已正确修改了DOM)。我还在服务器上看到POST请求成功并且设置了用户名。

  1. 200 OK

只是一个猜测,我尝试设置

aHttpExchange.sendResponseHeaders(200, 0);

,并在关闭OutputStream之前向其发送空字符串。这会导致赛普拉斯(以及处于非测试模式的普通浏览器)将这个空字符串设置为页面内容,所以这样做没有好处。

根据http spec

由POST方法执行的操作可能不会导致可以由URI标识的资源。在这种情况下,适当的响应状态是200(确定)或204(无内容),具体取决于响应是否包括描述结果的实体。

因此,似乎我的服务器应该对响应(1)做正确的事情。

有人知道为什么会超时吗?

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,而不用使用隐藏的表单元素来保存表单的名称,并在服务器端读取隐藏元素的内容以分派请求。