【问题标题】:xpath acts as though it clicks the button, but no real action is madexpath 的行为就像它单击按钮一样,但没有执行任何实际操作
【发布时间】:2016-01-31 08:08:11
【问题描述】:

我目前正在为 Web 应用程序开发自动化测试套件。 Web 应用程序真的很挑剔。最近,我们有一个 UI 更新,所以我运行测试来测试我们的 GUI 和按钮,以及访问我们的 xpath 是否仍在工作。

万圣节前夜,我的剧本变成了现实SPOOOOOOOKY~

在这些套件中,我有一组两个测试:yesLogout、noLogout。 yesLogout 在您尝试注销时单击“是”按钮。 noLogout 在您尝试注销时单击“否”按钮。

在测试脚本中运行 noLogout 时,脚本点击“否”,注销提示消失。

当您在测试脚本中运行 yesLogout 时,脚本会单击“是”按钮,但没有任何反应。 “是”按钮使动画看起来好像被点击了一样,但提示仍然存在。

手动点击按钮就可以了。

我将分享这两种方法(noLogout、yesLogout),因为它们实际上是相同的,它们只是调用了两个不同的 xpath。为了这个问题,忘记我正在测试 - 现在测试不是问题。假装我是一个真正需要我的脚本才能点击此按钮的怪人。

测试中使用的两个函数(极其简化):

public class HiStackOverflow {

    public class yesLogout {
        public static void run(WebDriver driver) throws FileNotFoundException {
            Properties prop = new Properties();
            InputStream selectproductsidebar;

            selectproductsidebar = new FileInputStream(
                "C:/PATH/TO/PROPERTIES");
            try {
                prop.load(selectproductsidebar);
            } catch (IOException e) {
                e.printStackTrace();
            }


            WebElement yesLogout = driver.findElement(By.xpath(prop.getProperty("yeslogout")));
            Actions actions = new Actions(driver);
            actions.moveToElement(yesLogout).build().perform();
            yesLogout.click();
        }
    }

    public class noLogout {
        public static void run(WebDriver driver) throws FileNotFoundException {
            Properties prop = new Properties();
            InputStream selectproductsidebar;

            selectproductsidebar = new FileInputStream(
                "C:/PATH/TO/PROPERTIES");
            try {
                prop.load(selectproductsidebar);
            } catch (IOException e) {
                e.printStackTrace();
            }


            WebElement noLogout = driver.findElement(By.xpath(prop.getProperty("nologout")));
            Actions actions = new Actions(driver);
            actions.moveToElement(noLogout).build().perform();
            noLogout.click();
        }

    }
}

属性文件中Yes按钮和No按钮的xpath:

yeslogout = //div[contains(@title,'Enter')]
nologout = //div[contains(@title,'Esc')]

这里是与问题相关的 HTML:

<div style="transform: translate(0px, 60px) scale(1, 1) rotate(0deg);">
  <div style="transform: translate(10px, 0px) scale(1, 1) rotate(0deg);">
    <div>
      <div tabindex="6" role="button" aria-label="Yes" title="Keyboard shortcut: Enter">
        <div>
        </div>
        <div tabindex="7" role="button" aria-label="No" title="Keyboard shortcut: Esc" style="transform: translate(163.5px, 0px) scale(1, 1) rotate(0deg);">
          <div>
          </div>
        </div>
      </div>
    </div>

tabindex="6" 是“是”按钮。 tabindex="7" 是否按钮。两者有一点点不同(no 按钮有某种转换:附加魔法转换),但就我而言,它不应该表现得那么奇怪。

再一次,实际问题 - 运行 yesLogout 方法定位、悬停并单击“是”按钮,但没有任何反应。手动单击“是”按钮效果很好。

如果需要,我可以在 html 中扩展更多 &lt;div&gt;s,但我真的不认为它会显示太多(只是更多的格式和 &lt;canvas&gt; 的东西)。我真的很想解释正在发生的事情。提前致谢。

编辑: 我曾尝试使用 JavascriptExecutor 来单击该元素,但很可惜,它不起作用。这整个周末都在绞尽脑汁。

甚至做一些疯狂的事情,比如:

WebElement yesLogout = driver.findElement(By.xpath(prop.getProperty("yeslogout")));
        Actions actions = new Actions(driver);
        actions.moveToElement(yesLogout, 10, 10).build().perform();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();
        yesLogout.click();

显示被反复点击的按钮,但没有实际功能。

为了完整起见并试图让人们理解这个问题,我会重申一下,手动点击按钮效果很好。与 Enter 快捷方式一样。 Selenium .click() 命令可见“工作”,但不执行按钮本身的功能。

第二次编辑: 我将包含一个完全扩展的相关 div 的 HTML:

<div style="transform: translate(794px, 202px) scale(1, 1) rotate(0deg);" tabindex="5" role="dialog">
  <div>
    <div>
      <div>
        <div>
          <div>
            <canvas height="106" width="332" style="top: 0px; left: 0px; width: 332px; height: 106px;" />
          </div>
        </div>
        <div style="transform: translate(10px, 10px) scale(1, 1) rotate(0deg);">
          <div>
            <div style="transform: translate(6px, 6px) scale(1, 1) rotate(0deg);">
              <div style="font-family: franklin-gothic-urw; font-weight: 400; font-style: normal; font-size: 14px; opacity: 1; color: rgb(0, 0, 0);">Are you sure you want to logoff?</div>
            </div>
          </div>
        </div>
        <div style="transform: translate(0px, 60px) scale(1, 1) rotate(0deg);">
          <div style="transform: translate(10px, 0px) scale(1, 1) rotate(0deg);">
            <div>
              <div tabindex="6" role="button" aria-label="Yes" title="Keyboard shortcut: Enter">
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                        </div>
                      </div>
                      <div style="transform: translate(56px, 7px) scale(1, 1) rotate(0deg);">
                        <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">Yes</div>
                      </div>
                      <div style="">
                        <div>
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                        </div>
                        <div style="display: none;">
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                          <div style="transform: translate(56px, 7px) scale(1, 1) rotate(0deg);">
                            <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">Yes</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div tabindex="7" role="button" aria-label="No" title="Keyboard shortcut: Esc" style="transform: translate(163.5px, 0px) scale(1, 1) rotate(0deg);">
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                        </div>
                      </div>
                      <div style="transform: translate(58px, 7px) scale(1, 1) rotate(0deg);">
                        <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">No</div>
                      </div>
                      <div style="display: none;">
                        <div>
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                        </div>
                        <div style="display: none;">
                          <div>
                            <canvas height="36" width="148" style="top: 0px; left: 0px; width: 148.5px; height: 36px;" />
                          </div>
                          <div style="transform: translate(58px, 7px) scale(1, 1) rotate(0deg);">
                            <div style="font-family: proxima-nova; font-weight: 400; font-style: normal; font-size: 17px; opacity: 1; color: rgb(255, 255, 255); transform: translate(5px, 0px) scale(1, 1) rotate(0deg);">No</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

【问题讨论】:

  • 您能否包含更多导致此问题的 html。我注意到 no 按钮包含在 yes 按钮中,这有点奇怪,并且该错误可能是由内部其他东西引起的。另外,如何将点击事件绑定到是按钮?
  • 另外,return false;还有其他绑定事件吗?
  • 点击事件是用一个WebElement yesLogout = driver.findElement(By.xpath(prop.getProperty("yeslogout"))) 从属性文件加载xpath,而不是我使用一个简单的yesLogout.click() 来点击它。我不相信有任何返回 false 的值。
  • 我指的是实际页面上的 JavaScript。
  • 我在这里做个猜测。按钮的单击处理程序是否可能由您的 JS 动态设置?当您手动运行它时,它有足够的时间进行设置并且点击发生得很好,但是 selenium 做得太快了吗?您可以尝试在单击之前添加 5 秒等待,看看是否有效吗?您还可以在单​​击并打印单击处理程序之前在页面中运行一些 javascript,以查看它是否设置正确(可能有助于调试)。看到这个:stackoverflow.com/questions/5327668/…

标签: javascript java html selenium xpath


【解决方案1】:

首先尝试使用不同的选项进行调试,例如通过键盘 Enter 键查看是否有效

WebElement.sendKeys(Keys.ENTER);

您可以尝试的其他选项是使用 CSS 查找元素或使用 Java 脚本方法单击元素

WebElement element = driver.findElement(By.id("gbqfd"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);

参考:How to click an element in Selenium WebDriver using JavaScript

【讨论】:

  • 我目前不在周末,但我会在周一的脚本中尝试。我从未听说过 Javascript 执行器。如果整个 Web 应用程序都是用 JavaScript 编写的,那么学习这一切是否明智?顺便谢谢。
  • 我之前也遇到过非常类似的情况,我只需要在点击工作之前使用 xpaths。这听起来像是一个真正的解决方案。
  • 这里不应该需要 JSE,一般来说,不应该使用 JSE。它以用户无法做到的方式与页面交互。如果您想模拟用户与您的页面的交互,并且您应该这样做,那么请不要使用 JSE。
  • 今天回到办公室。值得一试,但这似乎不起作用。
【解决方案2】:

有几件事可能会导致这种情况,但如果没有您将相关的 JavaScript 添加到您的问题中,我无法确定。我假设在您页面的 JavaScript 中某处,有一个绑定到 click 事件的函数,该函数实际上正在执行您期望的操作。

这个事件可能被绑定到yes 按钮的子级。在这种情况下,单击页面上的按钮可能会在浏览器中触发单击事件。但是,因为您的 xpath 以父元素为目标,所以 selenium 只会触发对该元素的点击事件,因此不会触发其子元素的任何事件。但是,如果动画附加到父级,仍可能会触发动画。这可以通过使 xpath 目标成为附加了 click 事件的特定元素来解决。

不幸的是,如果 JavaScript 是一团糟,那么查找事件附加到哪个元素可能会很痛苦。可能对您有所帮助的一件事是,如果您在 Chrome 开发人员工具中检查元素,则会出现一个事件侦听器选项卡。你可以看到哪些元素绑定了点击事件,但如果它们使用的是 jQuery,则不会显示具体的方法,而是使用 jQuery 方法之一。

【讨论】:

  • 谢谢詹姆斯。我现在就试试 Chrome 开发者工具,看看我能不能理解其中的任何一个。
  • 你的建议很有帮助,詹姆斯。我能够找到实际点击事件在脚本中的位置(而且,它的位置很荒谬)。我将这种方法用于我们脚本中的其他几个类似问题 - 效果很好。谢谢。
【解决方案3】:

我不知道这是否取决于您,但我会尝试为这些按钮添加 id 或更独特的属性(因为它们对应用程序很重要)。

另一方面,您一定需要actions.moveToElement() 吗?你不能只点击元素吗?这可以减少任何意外行为:

WebElement yesLogout = driver.findElement(By.xpath("..."));
yesLogout.click();

最后一件事(为了更好地理解),我不确定我是否理解您为什么要使用 div 作为按钮?为什么 No 按钮位于 (div) Yes 按钮内?这可能会导致问题。

【讨论】:

  • 老实说,要回答这些问题:我们的开发人员完全缺乏编码标准,我相信我们的应用程序正在运行它的第 3 年或第 4 年。当我试图自动化这件事时,我遇到了最疯狂的事情。我同意包含ids,整个程序中没有一个存在。
  • 基本上我对源代码没有太多控制权,所以我必须总是找到奇怪的方法来做事,同时什么也不硬编码。我也是实习生,所以告诉开发人员我们需要ids 可能不会被认真对待。我通常可以让事情正常工作 - 事实上,这个按钮的脚本大约在一周前工作,但他们更新了 GUI(使画布更大一点,绿色阴影不同),现在它不想听我。它知道我想做什么,只是拒绝实际执行按钮之外的功能。
  • 您能否提供更多html 代码。这样一来,就看不到你的大部分问题了:(
  • 我记得有一个“类似”问题,我可以手动单击一个元素,但它不适用于Selenium。问题是触发“预期动作”的元素不是我想的那个。这意味着,也许另一个 DOM 元素正在干扰您的点击(Selenium 专门点击一个元素,鼠标可能会在您的元素上方点击一个元素)。而且由于 HTML 代码看起来很乱,很可能发生了类似的事情。我希望它有帮助:)
  • 那肯定不是这样,哈哈...我会尝试询问 DOM 或 Javascript 中是否有某些内容,正如@James Brierley 在他的问题中提到的那样。我的意思是,问问这些人,即使他们创建了一个不那么可读的代码,他们也可能知道会发生什么。更像是:“嘿!发生了一些奇怪的事情,也许你可以帮我弄清楚......”:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
相关资源
最近更新 更多