Java NoTouchElementException-junit测试错误

Java NoTouchElementException-junit测试错误,java,html,selenium,junit,Java,Html,Selenium,Junit,我正在使用SeleniumJUnit测试。 如果我尝试使用selenium ide,测试进行得很顺利,但使用junit时会出现以下错误: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#firstName"} 我认为

我正在使用SeleniumJUnit测试。 如果我尝试使用selenium ide,测试进行得很顺利,但使用junit时会出现以下错误:

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#firstName"}
我认为span不会重定向到它应该重定向的页面(但在正常的时间表中它会重定向)

我尝试过xpath,但没有成功

带有跨距重定向的HTML页面:

<body>
    <div class="container text-center">
        <div align="center">
            <h2>Gestione dottori</h2>
            <table  class="table table-striped table-responsive-md">
                <tr>
                    <th>ID</th>
                    <th>Nome</th>
                    <th>Specialit&agrave</th>
                </tr>
                <tr th:each="doc: ${listDoc}">
                    <td th:text="${doc.getId()}"></td>
                    <td>Dr. <span th:text="${doc.getFirstName()}"></span> <span th:text="${doc.getLastName()}"></span></td>
                    <td th:text="${doc.getDoc_type()}"></td>
                </tr>
            </table>
            <a th:href = "@{/admin_createdoc}"><span id="btn_createDoc" class="plus bg-dark" >+</span></a>
            <hr>
            <div class="col col-lg-2 align-self-center">
                <div class="p-1">
                    <form th:action="@{/admin_logout}" method=post>
                        <button name="btn_logout_profile" id="btn_logout_profile"
                            type="submit" class="btn btn-primary">Log Out</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</body>

多托里宫
身份证件
诺姆
特殊照明与阿格拉夫酒店
博士

注销
哪个重定向到此页面:

<body>
    <div class="container">
        <div class="d-flex align-items-center justify-content-start">
            <form th:action="@{/admin_homepage}" method=get>
                <button name="btn_back_profile" id="btn_back_profile" type="submit"
                    class="btn btn-info">
                    <span class="fas fa-chevron-left"></span>
                </button>
            </form>
        </div>
        <br>
        <div style='text-align: center'>
            <form class="well form-horizontal" action="#"
                th:action="@{/saveDoctor}" th:object="${doc}" method="POST"
                id="contact_form">
                <fieldset>
                    <!-- Form Name -->
                    <legend>
                        <center>
                            <h2>
                                <b>Doctor Creation Form</b>
                            </h2>
                        </center>
                    </legend>
                    <br>

                    <!-- Text input-->

                    <div class="form-group">
                        <label class="col-md-4 control-label">First Name</label>
                        <div class="col-md-4 inputGroupContainer">
                            <div class="input-group">
                                <span class="input-group-addon"><i
                                    class="glyphicon glyphicon-user"></i></span> <input name="first_name"
                                    th:field="*{firstName}" placeholder="Doc First Name"
                                    class="form-control" type="text" required>
                            </div>
                        </div>
                    </div>

                    <!-- Text input-->

                    <div class="form-group">
                        <label class="col-md-4 control-label">Last Name</label>
                        <div class="col-md-4 inputGroupContainer">
                            <div class="input-group">
                                <span class="input-group-addon"><i
                                    class="glyphicon glyphicon-user"></i></span> <input name="last_name"
                                    th:field="*{lastName}" placeholder="Doc Last Name"
                                    class="form-control" type="text" required>
                            </div>
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-4 control-label">Type</label>
                        <div class="col-md-4 inputGroupContainer">
                            <div class="input-group">
                                <span class="input-group-addon"><i
                                    class="glyphicon glyphicon-list"></i></span> <input name="doc_type"
                                    th:field="*{doc_type}" placeholder="Doc Type"
                                    class="form-control" type="text" required>
                            </div>
                        </div>
                    </div>

                    <!-- Text input-->

                    <div class="form-group">
                        <label class="col-md-4 control-label">Id</label>
                        <div class="col-md-4 inputGroupContainer">
                            <div class="input-group">
                                <span class="input-group-addon"><i
                                    class="glyphicon glyphicon-user"></i></span> <input name="id"
                                    th:field="*{id}" placeholder="Doc ID" class="form-control"
                                    type="number" required>
                            </div>
                        </div>
                    </div>

                    <!-- Text input-->

                    <div class="form-group">
                        <label class="col-md-4 control-label">Password</label>
                        <div class="col-md-4 inputGroupContainer">
                            <div class="input-group">
                                <span class="input-group-addon"><i
                                    class="glyphicon glyphicon-user"></i></span> <input
                                    th:field="*{password}" name="doc_password"
                                    placeholder="Doc Password" class="form-control" type="password"
                                    required>
                            </div>
                        </div>
                    </div>

                    <!-- Button -->
                    <div class="form-group" align="center">
                        <label class="col-md-4 control-label"></label>
                        <div class="col-md-4">
                            <br>
                            <button type="submit" class="btn btn-warning">
                                SUBMIT <span class="glyphicon glyphicon-send"></span>
                            </button>
                        </div>
                    </div>
                </fieldset>
            </form>
            <div>
                <form th:action="@{/admin_logout}" method=post>
                    <button name="btn_logout_profile" id="btn_logout_profile"
                        type="submit" class="btn btn-primary">Log Out</button>
                </form>
            </div>
        </div>
    </div>
</body>


博士创作表
名字 姓 类型 身份证件 密码
提交 注销

谢谢你抽出时间

故障发生在这条线路上

driver.findElement(By.id("firstName")).click();
作为CSS选择器的ID是
#firstName
。由于这是在页面转换之后,我猜在运行下一行代码之前,页面没有完全加载。这种情况有时会发生在一个现代网站上,该网站加载了页面,但仍有一些内容在后台异步加载。修复方法是在以下行中添加等待,特别是
WebDriverWait
。这是一个选择

我宁愿编写帮助器方法来处理常见的操作,比如
click()
sendKeys()
,等等,然后让这些方法来处理特定的等待,而不是在发现需要时添加一个wait片段

public void click(By locator) {
    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(locator)).click();
}

public void sendKeys(By locator, String text) {
    findElement(locator).sendKeys(text);
}

public WebElement findElement(By locator) {
    return new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(locator));
}
然后您可以将脚本更改为

@Test
public void adminCreateDoc() {
    driver.get("http://localhost:8080/login");
    driver.manage().window().setSize(new Dimension(550, 706));
    click(By.linkText("Accesso amministratori"));
    sendKeys(By.id("username"), "8245");
    sendKeys(By.id("password"), "prova1");
    click(By.cssSelector(".btn"));
    click(By.id("btn_createDoc"));
    sendKeys(By.id("firstName"), "Marco");
    sendKeys(By.id("lastName"), "Battiato");
    sendKeys(By.id("doc_type"), "Cardiologo");
    sendKeys(By.id("id"), "855555");
    sendKeys(By.id("password"), "prova1");
    click(By.cssSelector(".glyphicon-send"));
}
我认为这使它更具可读性,在不需要额外代码的情况下为所有内容添加等待,等等


下一个级别是使用页面对象模型来包含每个页面的定位器和方法。然后,您的代码会得到显著的清理,使其接近人类可读性,并且更易于管理。

看起来错误发生在
driver.findElement(By.id(“firstName”)。单击()--没有ID为
firstName
的元素。您的
span#btn_createDoc
很好。也许你是说点击并没有像你期望的那样显示
firstName
元素?我认为这是一个重定向问题,因为在查找元素firstName之前尝试设置WebDriverWait,它没有进入它应该进入的页面,但是我对junit selenium是新手,所以我不确定这是否是问题所在。如果不知道整个页面的外观,很难判断。您可以尽可能多地共享HTML吗?在您单击看似按钮的按钮
btn_createDoc
后发生错误的事实告诉我,您需要在查找元素命令周围添加一些等待。它可能是从一个页面/屏幕转到另一个页面/屏幕,而find_element命令并没有等到DOM完全加载后才执行。如果它有助于更高层次的操作,我已经用更多的html代码修改了我的帖子+1.
@Test
public void adminCreateDoc() {
    driver.get("http://localhost:8080/login");
    driver.manage().window().setSize(new Dimension(550, 706));
    click(By.linkText("Accesso amministratori"));
    sendKeys(By.id("username"), "8245");
    sendKeys(By.id("password"), "prova1");
    click(By.cssSelector(".btn"));
    click(By.id("btn_createDoc"));
    sendKeys(By.id("firstName"), "Marco");
    sendKeys(By.id("lastName"), "Battiato");
    sendKeys(By.id("doc_type"), "Cardiologo");
    sendKeys(By.id("id"), "855555");
    sendKeys(By.id("password"), "prova1");
    click(By.cssSelector(".glyphicon-send"));
}