使用Websocket的Selenium测试用例单独通过,但如果一起运行则会失败

2cmtqfgy  于 2022-11-29  发布在  其他
关注(0)|答案(1)|浏览(170)

我有一个用于客户端页面的HTML页面,以及用于服务器函数的Java。服务器和客户端都连接到端口8800。这是我如何连接客户端和服务器:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>something</title>
</head>
<body>
<div ><button id="startButton" onclick="start()" style="visibility: hidden;">START</button></div>
<script type="text/javascript">
        var webSocket = new WebSocket("ws://localhost:8800");
        var startButton = document.getElementById("startButton");

        webSocket.onopen = function(event){ wsOpen(event);};
        webSocket.onmessage = function(event){ wsGetMessage(event);};
        webSocket.onclose = function(event){ wsClose(event);};
        webSocket.onerror = function(event){ wsError(event);};
        function start(){
            wsSendMessage("start,"+player_id);
            startButton.innerText = "STARTED";
            startButton.disabled="true";
        }
        function wsSendMessage(message){
            webSocket.send(message);
        }
    </script>
</body>
</html>

这是我的服务器的外观:

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.*;
public class Server extends WebSocketServer {
    public Server(int port) {
        super(new InetSocketAddress(port));
    }
    @Override
    public void onStart() {
        System.out.println("Server started!");
        setConnectionLostTimeout(0);
        setConnectionLostTimeout(500);
    }
something else

我用Selenium来测试网页。这是我的基本配置:

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;

import io.github.bonigarcia.wdm.WebDriverManager;
import java.nio.file.Path;
import java.nio.file.Paths;
import static org.junit.jupiter.api.Assertions.*;

public class Test {
    WebDriver driver1;

    String path = "path/web.html";
    Path sampleFile;
    Server server;
    JavascriptExecutor js1;

    @BeforeAll
    static void setupClass() {
        WebDriverManager.chromedriver().setup();
    }
    @BeforeEach
    void setup() throws InterruptedException {
        driver1 = new ChromeDriver();

        js1 = (JavascriptExecutor) driver1;

        sampleFile = Paths.get(path);
        server = new Server(8800);
        server.start();
    }
    @AfterEach
    void teardown() throws InterruptedException {
        driver1.quit();
    }

我的两个测试用例如下:

@Test
    void row41() throws InterruptedException {
        driver1.get(sampleFile.toUri().toString());

        driver1.findElement(By.id("startButton")).click();
       
        //some other operations
        assertEquals(2, server.getNextPlayer());
    }
    @Test
    void row42() throws InterruptedException {
        driver1.get(sampleFile.toUri().toString());
        driver1.findElement(By.id("startButton")).click();
        //some other operations

所以问题是,如果我分别运行两个测试,它们都将通过,但如果我一起运行它们,只有第一个测试将通过,第二个测试将失败,错误为

org.openqa.selenium.ElementNotInteractableException: element not interactable
  (Session info: chrome=107.0.5304.121)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:200)
    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:133)
    at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:184)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:167)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:142)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:567)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:251)
    at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:77)
    at project.Test.row42

而且从html页面本身的Angular 来看,startButton并没有加载和显示在页面上(但是如果页面连接到服务器,则会加载该按钮)。
为了缩小根本原因的范围,我制作了一个HTML页面的副本,并将其命名为web2.HTML,让它连接到端口8802(它连接到一个新的服务器示例,监听端口8802)。我在测试1中运行了web.html,在测试2中运行了web2.html,它们都通过了。所以我假设这是因为客户端和服务器连接的端口没有完全释放,因此出现了错误?
如果同时运行,则对于测试1,在onStart()中打印ウServer started Ж,而不是在测试2中打印。

dxpyg8gm

dxpyg8gm1#

原因是您在tearDown时没有关闭WS服务器。因为您的测试是在同一个进程中运行的,所以完成测试不会导致终止服务。
可能是因为端口被占用,而您正在使用上一个测试更改的状态(而不是清除的状态),所以它无法启动新的端口。

相关问题