Selenium ChromeDriver如何点击x,y像素位置为负的元素?C#

本文关键字:元素 位置 像素 ChromeDriver 何点击 Selenium | 更新日期: 2023-09-27 17:57:36

我正在处理一个有弹出表的网站。例如,如果用户在链接上悬停或单击,则会出现一个带有数据表的小弹出窗口。同一页面上有许多这样的链接。从表格中提取数据包括按顺序单击链接,依次打开和关闭每个弹出窗口。

关闭弹出窗口需要点击弹出窗口右上角的一个小"X"按钮。在99%的情况下,这不是一个问题。然而,大约1%的时间,弹出窗口的顶部将位于屏幕上方,具有负的"y"像素位置,隐藏关闭弹出窗口的"X"按钮,进而为其提供负的"y"像素位置。通过手动操作(手动移动鼠标),我可以调整Chrome窗口的大小,弹出窗口将"快速"返回窗口,最小"y"像素位置为零。

我还无法使用Selenium命令复制这个弹出窗口的手动重新居中。我能找到的最接近的命令是MoveToElement,它有时有效,但在其他情况下无效(我无法理解为什么我看到了部分成功,但这是对这个问题的题外话)。

据我所知,Selenium不允许我与x或y像素位置为负的元素交互。

以下是我目前正在尝试的,但收效甚微:

// example begins with pop-up already displayed. Data has been extracted.
// We are now ready to close the pop-up by clicking the 'X' button.
// here we move to the table, otherwise the detail popup close button will be off screen. Warning: this works with partial success. 
var actions = new Actions(Session.Driver);
actions.MoveToElement(table);
actions.Perform();
// Must close unless the popup may (or may not) cover the next link.
var closeButton = Session.Driver.FindElement(By.Id(id))
    .FindElements(By.CssSelector("a.cmg_close_button"))
    .FirstOrDefault();
if (closeButton != null)
{
    Wait.Until(d => closeButton.Displayed);
    if (closeButton.Location.Y < 0 || closeButton.Location.X < 0)
    {
        Log.Error("Could not close button. The popup displayed the close_button off-screen giving it a negative x or y pixel location.");
    }
    else
    {
        closeButton.Click();
    }
}

请告知处理弹出窗口负x,y像素位置的策略。

我使用的是C#4.6、Selenium 2.45、ChromeDriver(Chrome)和VS2015 CE IDE。

Selenium ChromeDriver如何点击x,y像素位置为负的元素?C#

当链接靠近视图边界时,页面似乎没有正确设置弹出窗口的位置。

为了克服这个问题,您可以先将目标元素滚动到视图的中心,然后再移动到它上面:

// scroll the link close to the center of the view
Session.Driver.ExecuteScript(
  "arguments[0].scrollIntoView(true);" +
  "window.scrollBy(-200, -200);" ,
  table);
// move the mouse over
new Actions(Session.Driver)
  .MoveToElement(table)
  .Perform();

Selenium被设计为只与用户可以交互的元素交互。在大多数情况下,这更多地适用于页面上的隐藏元素。根据我的经验,您有一种罕见的情况,即您的"隐藏"元素不在页面上,而不是display:none等。

解决这一问题的一种方法是使用IJavaScriptExecutor。这将允许您在页面上运行JS代码注意:如果你试图坚持严格的用户场景,即只做用户可以做的事情,这不适合你。您需要继续研究如何将弹出窗口重新显示在屏幕上。

我认为如果你改变你的剧本,如下,它应该会起作用。

if (closeButton.Location.Y < 0 || closeButton.Location.X < 0)
{
    IJavaScriptExecutor jse = Session.Driver as IJavaScriptExecutor;
    jse.ExecuteScript("arguments[0].click()", closeButton);
    // Log.Error("Could not close button. The popup displayed the close_button off-screen giving it a negative x or y pixel location.");
}
else
{
    closeButton.Click();
}