在 Selenium 中显示当前光标位置

问题描述 投票:0回答:6

有没有办法显示当前光标位置或类似的东西?我有一个动作链,应该点击某个对象上的确切点,但我想我选择了错误的坐标。我使用 Firefox 网络驱动程序。 脚本如下所示:

from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get("http://www.mysite/")
elem = driver.find_element_by_xpath('//div[@id="player"][1]/object[@type="application/x-shockwave-flash"]')
action_chains = ActionChains(driver)
action_chains.move_to_element_with_offset(elem, 660, 420).perform()
action_chains.click().perform()
time.sleep(10)
driver.close()
python flash testing selenium selenium-webdriver
6个回答
6
投票

我有一个不透明的 HTML5 画布,我必须在其中检查不同偏移处的工具提示值,这真是太麻烦了!经过多次敲头之后,我学到了几件重要的事情:

  1. move_to_element_by_offset
    在 2.42 之前存在问题。另请参阅https://code.google.com/p/selenium/issues/detail?id=4215

  2. 即使更新后,

    move_to_element_by_offset
    仍然显得很挑剔。我切换到
    ActionChains move_to_element
    悬停(默认为元素中心)和第二个
    ActionChains
    move_by_offset

  3. 的组合
  4. 现在您已就位,请重新请求位置敏感元素。就我而言,这是一个工具提示对象。这个

    selenium.webdriver.remote.element
    将拥有您需要进行健全性检查的
    .location['x']
    .location['y']
    成员。

perform
'd ActionChain 悬停后无法抓取光标位置的事情,以节省每个人一些时间:

  • .location['x']
    .location['y']
    位于您传入
    move_to_element
    的元素上。这些值不会由
    ActionChains
    更新。
  • selenium.webdriver.remote.webdriver
    switch_to_active_element
    ;我不清楚哪些元素符合“活动”元素,但它不承认我们的工具提示是活动元素,并给了我 [0, 0] 坐标。
  • selenium.webdriver.remote.webdriver
    get_window_position
    ;文档有点含糊,但这正是函数所建议的:一个窗口而不是光标位置。

5
投票

如果您只想确认 Selenium 是否单击了正确的元素,而不是对该元素进行

click()
-ing:

actions.move_to_element(my_element).click().perform()

context_click()
在上面:

actions.move_to_element(my_element).context_click().perform()

Selenium 将右键单击您的元素,这将导致上下文菜单显示在光标的右下角。一旦你看到上下文菜单的位置,你就会知道 Selenium 是否点击了正确的元素。


4
投票

是的,这个问题令人沮丧。

这个方法可以让你通过在鼠标上画一个红点来查看鼠标所在的位置: enter image description here 首先暂时将以下 CSS 添加到您的网页:

// TODO: Remove me after you've figured out where the mouse is moving to.
.dot {
  background: red;
  position: absolute;
  width: 2px;
  height: 2px;
  z-index: 10000;
}

然后,在您的代码中,在调用

*.moveTo()
方法之前,添加一个暂停,以允许您将代码注入浏览器的控制台。此代码采用 JavaScript (JS / webdriver.io) 编写,但可以轻松以任何语言添加:

// Other test stuff...

console.log("This gives you 10 seconds to inject the code..."); // <-- Add this and the next line
browser.pause(10000);

browser.moveTo(...gawdKnowsWhere);

现在,当您看到测试命令行控制台正在等待 10 秒时,打开 Chrome/Firefox 的开发人员工具 (F12) 并将此代码段粘贴到浏览器的“控制台”选项卡中:

  (function() {
    "use strict";

    document.onmousemove = handleMouseMove;
    function handleMouseMove(event) {
      var dot, eventDoc, doc, body, pageX, pageY;
      
      event = event || window.event; // IE-ism
      
      // If pageX/Y aren't available and clientX/Y
      // are, calculate pageX/Y - logic taken from jQuery
            // Calculate pageX/Y if missing and clientX/Y available
      if (event.pageX == null && event.clientX != null) {
        eventDoc = (event.target && event.target.ownerDocument) || document;
        doc = eventDoc.documentElement;
        body = eventDoc.body;

        event.pageX = event.clientX +
          (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
          (doc && doc.clientLeft || body && body.clientLeft || 0);
        event.pageY = event.clientY +
          (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
          (doc && doc.clientTop  || body && body.clientTop  || 0 );
      }

      // Add a dot to follow the cursor
      dot = document.createElement('div');
      dot.className = "dot";
      dot.style.left = event.pageX + "px";
      dot.style.top = event.pageY + "px";
      document.body.appendChild(dot);
    }
  })();

现在,去寻找红点。无论鼠标移动到哪里,它都无法单击那里,因为现在有一个红色方块挡住了。但至少你可以看到它试图去往的地方。

看不到点?

一些提示:

  • 通过修改宽度和高度使 CSS 中的点变大。
  • 将鼠标移过屏幕并观察所有红点。当您移动鼠标时它们会出现吗?
  • 确保您可以在您期望的位置画一个红点。 z 顺序可能不够高等等。

0
投票

我没有看到任何可能的方法来直接更改分辨率,因为我们不能使用任何定位器。

对于 JWPlayer 的示例,我确信可能有一些 javascript 片段允许更改分辨率。使用 Selenium JavascriptExecutor,您可以运行该 javacript 代码来模拟分辨率更改..尽管不是通过单击光标来实现。

WebDriver driver = new ChromeDriver();

if (driver instanceof JavascriptExecutor) {
    ((JavascriptExecutor) driver).executeScript(YOUR_JAVA_SCRIPT_STRING);
}

我注意到您提到您不想使用任何本机 JWPlayer API。我认为这是唯一可能的解决方案。


0
投票

作为一名 Selenium 新手,我有点难以理解它无法生成 Flash 对象的点击。我在这里看到的唯一可能的解决方案是使用

sikuli-script

我在 GitHub 上找到了该项目:https://github.com/kevlened/sikuli_cpython。它允许在纯Python中使用sikuli脚本(用jython编写),所以我想我将能够编写一些sikuli脚本并将它们与selenium测试集成。


0
投票

这是我能想到的最好的答案,但给出光标的 x ,y 坐标可以完美地工作。 ` def main(): 尝试: driver.get(LOGIN_URL)

    # Inject the JavaScript code
    js_code = """
    document.addEventListener('mousemove', updateCursorPosition);
    function updateCursorPosition(event) {
        window.cursorX = event.clientX;
        window.cursorY = event.clientY;
    }
    """
    driver.execute_script(js_code)
    time.sleep(2)  # Give the JavaScript code time to set up

    while True:
        # Retrieve the cursor position values
        cursor_x = driver.execute_script("return window.cursorX || 0;")
        cursor_y = driver.execute_script("return window.cursorY || 0;")
        print(f"Cursor Position: X = {cursor_x}, Y = {cursor_y}")

        time.sleep(0.5)  # Adjust the interval as needed

except Exception as e:
    logging.error(f"An error occurred: {e}")
    # Optionally log more details only in development/debugging:
    # if __debug__:
    #     logging.error(traceback.format_exc())

finally:
    driver.quit()`

下面的js代码可用于在浏览器中的ui上标记位置(只需将其替换为上面的js代码即可)
document.addEventListener('mousemove', createCircle);

    function createCircle(event) {
        const circle = document.createElement('div');
        circle.style.position = 'absolute';
        circle.style.width = '20px';
        circle.style.height = '20px';
        circle.style.borderRadius = '50%';
        circle.style.backgroundColor = 'red';
        circle.style.left = (event.clientX - 10) + 'px'; // Center the circle
        circle.style.top = (event.clientY - 10) + 'px';  // Center the circle
        circle.style.zIndex = 9999; // Ensure it's on top
        document.body.appendChild(circle);
        setTimeout(() => {
            circle.remove();
        }, 1000); // Remove after 1 second
    }
© www.soinside.com 2019 - 2024. All rights reserved.