有没有办法显示当前光标位置或类似的东西?我有一个动作链,应该点击某个对象上的确切点,但我想我选择了错误的坐标。我使用 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()
我有一个不透明的 HTML5 画布,我必须在其中检查不同偏移处的工具提示值,这真是太麻烦了!经过多次敲头之后,我学到了几件重要的事情:
move_to_element_by_offset
在 2.42 之前存在问题。另请参阅https://code.google.com/p/selenium/issues/detail?id=4215即使更新后,
move_to_element_by_offset
仍然显得很挑剔。我切换到 ActionChains move_to_element
悬停(默认为元素中心)和第二个 ActionChains
与 move_by_offset
现在您已就位,请重新请求位置敏感元素。就我而言,这是一个工具提示对象。这个
selenium.webdriver.remote.element
将拥有您需要进行健全性检查的 .location['x']
和 .location['y']
成员。在
perform
'd ActionChain 悬停后无法抓取光标位置的事情,以节省每个人一些时间:
.location['x']
和 .location['y']
位于您传入 move_to_element
的元素上。这些值不会由 ActionChains
更新。switch_to_active_element
;我不清楚哪些元素符合“活动”元素,但它不承认我们的工具提示是活动元素,并给了我 [0, 0] 坐标。get_window_position
;文档有点含糊,但这正是函数所建议的:一个窗口而不是光标位置。如果您只想确认 Selenium 是否单击了正确的元素,而不是对该元素进行
click()
-ing:
actions.move_to_element(my_element).click().perform()
context_click()
在上面:
actions.move_to_element(my_element).context_click().perform()
Selenium 将右键单击您的元素,这将导致上下文菜单显示在光标的右下角。一旦你看到上下文菜单的位置,你就会知道 Selenium 是否点击了正确的元素。
这个方法可以让你通过在鼠标上画一个红点来查看鼠标所在的位置: 首先暂时将以下 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);
}
})();
现在,去寻找红点。无论鼠标移动到哪里,它都无法单击那里,因为现在有一个红色方块挡住了。但至少你可以看到它试图去往的地方。
一些提示:
我没有看到任何可能的方法来直接更改分辨率,因为我们不能使用任何定位器。
对于 JWPlayer 的示例,我确信可能有一些 javascript 片段允许更改分辨率。使用 Selenium JavascriptExecutor,您可以运行该 javacript 代码来模拟分辨率更改..尽管不是通过单击光标来实现。
WebDriver driver = new ChromeDriver();
if (driver instanceof JavascriptExecutor) {
((JavascriptExecutor) driver).executeScript(YOUR_JAVA_SCRIPT_STRING);
}
我注意到您提到您不想使用任何本机 JWPlayer API。我认为这是唯一可能的解决方案。
作为一名 Selenium 新手,我有点难以理解它无法生成 Flash 对象的点击。我在这里看到的唯一可能的解决方案是使用
sikuli-script
。
我在 GitHub 上找到了该项目:https://github.com/kevlened/sikuli_cpython。它允许在纯Python中使用sikuli脚本(用jython编写),所以我想我将能够编写一些sikuli脚本并将它们与selenium测试集成。
这是我能想到的最好的答案,但给出光标的 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
}