Можете ли вы отслеживать положение мыши на веб-странице в веб-браузере Selenium? C# - PullRequest
0 голосов
/ 31 января 2020

Я пытаюсь отслеживать координаты мыши в браузере Selenium.

В Selenium нет функций отслеживания мыши. Он имеет только функции MoveByOffset(int x, int y) и MoveToElement(IWebElement). Мне нужно установить пользовательские позиции и перейти к ним с помощью функции MoveByOffset(int x, int y).

Selenium позволяет использовать сценарий JavaScript, но, похоже, не позволяет запускать сценарий в фоновом режиме и извлекать значения из указанного Фоновая функция:

Мы могли бы выполнить что-то вроде:

document.onmousemove = function(e)
{
    var x = e.pageX;
    var y = e.pageY;
};

и вернуть из него значения, но это не представляется возможным (объяснено выше).

Мы также могли бы создать расширение Chrome и поместить скрипт в background.js, но я не смог найти способ извлечь значение из расширения и использовать его в коде. Возможно ли это?

Я также пытался отслеживать движение мыши в коде C#, но это не похоже на надежность:

Мы обычно нужно прокрутить страницу. Это можно сделать с помощью: js.ExecuteScript("window.scrollBy(0," + scrollDownAmountInPixels + ")");, где js - это IJavaScriptExecutor. Но прокрутка также двигает мышь. Мы могли бы обновить значение mouse-y до значения прокрутки, но если мы находимся в верхней части страницы и прокручиваем вверх ИЛИ, если находимся внизу страницы и прокручиваем вниз - мышь получит неправильные координаты. Мы могли бы проверить такие вещи, как page height, расстояние окна от верхней части страницы (scroll amount) и расстояние от окна до нижней части страницы (page height - (scroll amount + window height size)), НО JavaScript любит возвращать 0 вместо некоторых из этих значений в определенных c местах страницы. Я попытался прокрутить по пикселям, чтобы найти местоположение, в котором JavaScript не вернет 0 в нужных значениях, но это просто становится слишком ненадежным.

Я действительно надеюсь найти некоторую помощь здесь. Заранее спасибо!

1 Ответ

0 голосов
/ 02 февраля 2020

Итак, я создал этот класс. Он отслеживает координаты мыши, но иногда он может немного испортить их (несколько исправлено, но все еще может) .

Чтобы использовать его, вы должны вызывать NewPage() всякий раз, когда вы загрузить новую веб-страницу, НО только после ее полной загрузки. Затем вы можете использовать MoveTo(), передавая x, y координаты или IWebElement, чтобы переместить курсор в его местоположение. Вы можете использовать Scroll(), если вам нужно прокрутить страницу на y пикселей. И вы можете нажать с помощью Click().

Вот код:

public class MouseMover
        {
            public int PageHeight { get; private set; }
            public int PageScrolled { get; private set; }
            public int WindowHeight { get; private set; }
            public int MouseXCurr { get; private set; } // current mouse x position
            public int MouseYCurr { get; private set; } // current mouse y position

            private int MouseXToMove { get; set; }
            private int MouseYToMove { get; set; }
            private ChromeDriver Chr { get; set; }
            private Actions click;

            public MouseMover(ChromeDriver chr)
            {
                MouseXCurr = 0;
                MouseYCurr = 0;
                MouseXToMove = 0;
                MouseYToMove = 0;
                Chr = chr;
                NewPage();
                click = new Actions(chr);
                click.Click().Build();
            }

            public void NewPage() // call this whenever entering a new page and it is fully loaded in
            {
                IJavaScriptExecutor js = (IJavaScriptExecutor)Chr;

                Int64.TryParse(js.ExecuteScript("" +
                "var body = document.body," +
                "    html = document.documentElement;" +
                "" +
                "var height = Math.max(body.scrollHeight, body.offsetHeight," +
                "                         html.clientHeight, html.scrollHeight, html.offsetHeight);" +
                "return height;").ToString(), out long ph);
                PageHeight = (int)ph;

                if (PageScrolled != 0)
                {
                    MouseYCurr -= PageScrolled;
                }
                PageScrolled = 0;

                Int64.TryParse(js.ExecuteScript("return window.innerHeight;").ToString(), out long wh);
                WindowHeight = (int)wh;
            }

            public void Click() // click at the current mouse position
            {
                click.Perform();
            }

            public void Scroll(int y) // scroll the page by y pixels down (negative to scroll up)
            {
                IJavaScriptExecutor js = (IJavaScriptExecutor)Chr;
                int oldScroll = PageScrolled;
                if (y > 0)
                {
                    if (PageScrolled + WindowHeight + y <= PageHeight)
                    {
                        js.ExecuteScript("window.scrollBy(0," + y + ")");
                        PageScrolled += y;

                        // sometimes the ScrollHeight gets messed up. This helps to fix it, but it doesn't always fix it
                        Int64.TryParse(js.ExecuteScript("return (window.pageYOffset || document.documentElement.scrollTop)  - (document.documentElement.clientTop || 0);").ToString(), out long s);
                        if (s != 0 && PageScrolled != (int)s)
                        {
                            PageScrolled = (int)s;
                        }

                        MouseYCurr += PageScrolled - oldScroll;
                    }
                    else
                    {
                        if (PageHeight != PageScrolled + WindowHeight)
                        {
                            js.ExecuteScript("window.scrollBy(0," + (PageHeight - (PageScrolled + WindowHeight)) + ")");
                            PageScrolled += (PageHeight - (PageScrolled + WindowHeight));

                        // sometimes the ScrollHeight gets messed up. This helps to fix it, but it doesn't always fix it
                            Int64.TryParse(js.ExecuteScript("return (window.pageYOffset || document.documentElement.scrollTop)  - (document.documentElement.clientTop || 0);").ToString(), out long s);
                            if (s != 0 && PageScrolled != (int)s)
                            {
                                PageScrolled = (int)s;
                            }

                            MouseYCurr += PageScrolled - oldScroll;
                        }
                    }
                }
                else
                {
                    if (PageScrolled >= -y)
                    {
                        js.ExecuteScript("window.scrollBy(0," + y + ")");
                        PageScrolled += y;

                        // sometimes the ScrollHeight gets messed up. This helps to fix it, but it doesn't always fix it
                        Int64.TryParse(js.ExecuteScript("return (window.pageYOffset || document.documentElement.scrollTop)  - (document.documentElement.clientTop || 0);").ToString(), out long s);
                        if (s != 0 && PageScrolled != (int)s)
                        {
                            PageScrolled = (int)s;
                        }

                        MouseYCurr += PageScrolled - oldScroll;
                    }
                    else
                    {
                        js.ExecuteScript("window.scrollBy(0," + -PageScrolled + ")");
                        PageScrolled -= PageScrolled;

                        // sometimes the ScrollHeight gets messed up. This helps to fix it, but it doesn't always fix it
                        Int64.TryParse(js.ExecuteScript("return (window.pageYOffset || document.documentElement.scrollTop)  - (document.documentElement.clientTop || 0);").ToString(), out long s);
                        if (s != 0 && PageScrolled != (int)s)
                        {
                            PageScrolled = (int)s;
                        }

                        MouseYCurr += PageScrolled - oldScroll;
                    }
                }
            }

            public void MoveTo(IWebElement el) // move to the middle of the given web element
            {
                MoveTo(el.Location.X + el.Size.Width / 2, el.Location.Y + el.Size.Height / 2);
            }

            public void MoveTo(int x, int y) // move to the given page coordinates
            {
                MouseXToMove = x - MouseXCurr;
                MouseYToMove = y - MouseYCurr;
                Move();
            }

            void Move()
            {
                bool retry;
                do
                {
                    try
                    {
                        retry = false;
                        Actions actions = new Actions(Chr);
                        actions.MoveByOffset(MouseXToMove, MouseYToMove).Build().Perform();

                        // this will only be executed when the target coordinates enter the screen
                        MouseXCurr += MouseXToMove;
                        MouseYCurr += MouseYToMove;
                        MouseXToMove = 0;
                        MouseYToMove = 0;
                    }
                    catch
                    {
                        retry = true;
                        if (MouseYToMove > 0)
                        {
                            int oldScroll = PageScrolled;
                            Scroll(50);
                            MouseYToMove -= PageScrolled - oldScroll;
                        }
                        else
                        {
                            int oldScroll = PageScrolled;
                            Scroll(-50);
                            MouseYToMove -= PageScrolled - oldScroll;
                        }
                    }
                }
                while (retry == true);
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...