在Selenium中显示当前光标位置

12 投票
5 回答
36112 浏览
提问于 2025-04-18 01:19

有没有办法显示当前光标的位置或者类似的东西?我有一个动作链,它应该在某个对象的确切位置点击,但我想我选错了坐标。我使用的是Firefox的webdriver。下面是我的脚本:

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()

5 个回答

0

我没有找到直接改变分辨率的方法,因为我们无法使用任何定位器来做到这一点。

关于你提到的JWPlayer,我相信可能有一些JavaScript代码可以用来改变分辨率。你可以使用Selenium的JavascriptExecutor来运行这段JavaScript代码,从而模拟分辨率的变化,不过这不是通过点击鼠标来实现的。

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中使用用jython写的sikuli脚本,所以我想我可以写一些sikuli脚本,并把它们和selenium测试结合起来。

4

是啊,这个问题真让人头疼。

这个方法可以让你看到鼠标的位置,通过在鼠标上画一个红点来实现:

这里输入图片描述

首先,暂时在你的网页上添加以下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中通过修改宽度和高度来让红点变大。
  • 移动你的鼠标在屏幕上,看看所有的红点。当你移动鼠标时,它们有出现吗?
  • 确保你可以在你预期的位置画出红点。可能是层级不够高等等。
5

如果你只是想确认Selenium是否点击了正确的元素,而不是直接用click()去点击那个元素的话:

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

可以用context_click()来操作:

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

Selenium会对你的元素进行右键点击,这样就会在你鼠标的右下角显示出一个右键菜单。等你看到这个菜单的位置,就能知道Selenium是不是点击了正确的元素。

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. 现在你已经到位了,重新请求位置敏感的元素。在我的例子中,就是一个工具提示对象。这个selenium.webdriver.remote.element会有.location['x'].location['y']这两个属性,帮助你检查位置是否正确。

以下是一些在执行perform的ActionChain悬停后,获取光标位置时不管用的东西,省得大家浪费时间:

  • .location['x'].location['y']在你传给move_to_element的元素上。这些值不会被ActionChains更新。
  • selenium.webdriver.remote.webdriverswitch_to_active_element;我不太清楚哪些元素算“活动”,但它并没有把我们的工具提示视为活动元素,返回的坐标是[0, 0]。
  • selenium.webdriver.remote.webdriverget_window_position;文档有点模糊,但这个功能确实是获取窗口的位置,而不是光标的位置。

撰写回答