【问题标题】:Selenium Chrome window running in second monitor screen stealing focus在第二个监视器屏幕中运行的 Selenium Chrome 窗口窃取焦点
【发布时间】:2018-02-28 08:17:02
【问题描述】:

我将 WebDriver 与带有 Selenium 的 Chrome 驱动程序 2.35 一起使用。

我有一个双显示器设置,我在其中运行我的测试用例。大多数时候我确实在无头的情况下运行我的案例,但有时,当我想调试时,我会使用浏览器运行它。

窗口打开,我将它拖到我的第二台显示器上并继续在我的主显示器中处理其他内容。但是,每当 Chrome Selenium 辅助屏幕中有操作时,焦点就会转移到那个窗口,我就会失去控制。

这真的很烦人,有其他人遇到过这个问题吗?有什么解决办法吗?

【问题讨论】:

  • 也许这是 Chrome 的专长,因为我使用的是 Firefox,它只会在测试开始时窃取焦点,但在后台运行良好。您可以尝试使用 Firefox 来查看它是否依赖于浏览器吗?
  • 是的,确实是浏览器的问题。 Firefox 工作得很好。但是,仍然感到沮丧的是,它在 Chrome 中无法以这种方式工作。
  • 我在某些电脑上遇到了同样的问题。它从 ChromeDriver 2.29 开始,所以 ChromeDriver 2.28 也可以正常工作。

标签: google-chrome selenium


【解决方案1】:

Selenium chromedriver 在启动时只一次 窃取焦点。之后您可以在后台运行浏览器而不会出现任何问题(我们正在这样做,使用 chromedriver 2.30,所以我确信它可以工作)

因此,您的网络测试中可能有一些执行焦点窃取的代码:

1) 更改活动窗口或打开新窗口/新标签会导致焦点窃取。

2) 在元素上显式调用 Focus()。

您确定您的代码没有此类调用吗?

【讨论】:

  • 在我们的例子中,我们确信,因为代码在其他机器上运行良好。只有其中一些人受到这种行为的影响
  • 我假设您使用的是与 chromedriver 版本匹配的便携式 chrome。在这种情况下,您是否尝试过删除配置文件和/或以隐身模式启动 chromedriver?
  • 我有一个案例,我确实更改了活动窗口(选项卡),并尝试了 Rescis 的答案,但没有解决问题。我确实可以确认切换活动选项卡是导致浏览器窗口窃取焦点的原因。你可以在这里找到我的具体问题:stackoverflow.com/questions/49262548/…
  • 就我而言,所有操作都发生在同一个窗口中,我不会在选项卡或窗口之间切换。专注于设置和选择等琐碎功能。我使用 ChromeDriver 2.35,我有一个模糊的记忆,它曾经在旧版本中更好。在旁注中 - Chrome Headless 效果很好!
【解决方案2】:

我建议将窗口位置设置为始终位于底部。在 C# 中,您可以通过如下所示的类来执行此操作:

public static class SetWindowPosition
{
    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
    static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
    private const UInt32 SWP_NOSIZE = 0x0001;
    private const UInt32 SWP_NOMOVE = 0x0002;
    private const UInt32 SWP_NOACTIVATE = 0x0010;

    [DllImport("user32.dll")]
    private static extern bool LockSetForegroundWindow(uint uLockCode);
    private const UInt32 LSFW_LOCK = 1;

    public static void ForceWindowToStayOnBottom(Process process)
    {
        SetWindowPos(
            process.MainWindowHandle, // The handle of the browser window
            HWND_BOTTOM, // Tells it the position, in this case the bottom
            0, 0, 0, 0, // Coordinates for sizing of the window - Will be overriden by NOSIZE
            SWP_NOSIZE | // Says to keep the window its current size
            SWP_NOMOVE | // Says to keep the window in its current spot
            SWP_NOACTIVATE // Activation brings the window to the top, we don't want that
        );

        // If you don't notice this helping, it can probably be deleted.
        // It only deals with other applications and gets automatically undone on user interaction
        LockSetForegroundWindow(
            LSFW_LOCK); // Locks calls to SetForegroundWindow 
    }

    /// <returns> Returns the parent process of each process by the name of processName </returns>
    public static List<Process> GetPrimaryProcesses(string processName) =>

        Process.GetProcesses() // Gets a list of every process on computer
            .Where(process => process.ProcessName.Contains(processName) // Reduces the list to every process by the name we are looking for
                && process.MainWindowHandle != IntPtr.Zero) // Removes any process without a MainWindow (which amounts to every child process)
            .ToList();
}

称为:

SetWindowPosition.ForceWindowToStayOnBottom(
    SetWindowPosition.GetPrimaryProcesses("chrome")[0]);

其中[0] 是您要最小化的窗口的索引(通常它们按打开的顺序返回)。

这与您将窗口设置为 AlwaysOnTop 时所做的类似(例如,尝试打开任务管理器,单击选项,然后选择 Always On Top),但相反。您应该可以在任何您喜欢的进程上调用它,包括 Web 驱动程序控制台窗口。

如果您想进一步了解它的工作原理,这两个帖子(12)是我用来让它工作的,以及 MSDN 文档here

【讨论】:

  • 我喜欢这种方法,没想到。可悲的是,我们在其中一台受影响的计算机上进行了尝试,但并没有解决问题。我们对此感到非常困惑。
  • @Sosian 我只是花了一些时间在玩它,我注意到获取错误的窗口句柄存在问题,所以我用一个名为“GetPrimaryProcesses”的方法更新了它应该处理那。否则,我对它为什么不适合你的唯一猜测是它强迫自己进入前台,所以我添加了 LockSetForeground 方法来解决这个问题。否则,你能描述一下它是如何不工作的吗?
【解决方案3】:

我解决焦点被盗的方法一直是只使用虚拟机或远程计算机,并在需要时远程连接到进程以进行调试。

【讨论】:

  • 是的,我设置了双显示器以避免这样做,但显然拥有远程机器或虚拟机可能是最好的出路。
【解决方案4】:

即使我遇到了这个问题,我找到的解决方案是我从第二台显示器运行我的解决方案(即)将 Eclipse 拖到第二台显示器,然后运行测试。

【讨论】:

    猜你喜欢
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2016-04-09
    相关资源
    最近更新 更多