2022年2月22日 星期二

Selenium Page down by ActionChains

I had to click on the body for the Keys.PAGE_DOWN to work but didn't need to use the action chain:

from selenium.webdriver.common.keys import Keys

body = driver.find_element_by_css_selector('body')
body.click() 

body.send_keys(Keys.PAGE_DOWN) 


from: https://stackoverflow.com/questions/39471163/selenium-page-down-by-actionchains/39472743

Send Keys shift+tab on Selenium Web driver

 Shamelessly copied from https://www.programcreek.com/python/example/97717/selenium.webdriver.common.keys.Keys.SHIFT

a = ActionChains(driver)
a.key_down(Keys.SHIFT).send_keys(Keys.TAB).key_up(Keys.SHIFT)
a.perform()


from: https://stackoverflow.com/questions/56691117/send-keys-shifttab-on-selenium-web-driver

2020年7月27日 星期一

Behave 1.2.7 - "No tests were found"

Steps

  1. Install behave 1.2.7dev1 (I used this guide https://behave.readthedocs.io/en/latest/install.html)
  2. Run the minimal behave test (https://behave.readthedocs.io/en/latest/tutorial.html)

Expected

Tests are passed

Result

"No tests were found" error.

Additional info

  • Running behave from the terminal works correctly. Issue reproduced only using IDE run configuration.
  • Reinstalling behave to 1.2.6 and running the same run configuration works correctly

selenium: wait for element to be clickable not working

I'm attempting to use expected_conditions.element_to_be_clickable but it doesn't appear to be working. I'm still seeing "Element...is not clickable at point" errors in about 30% of the runs.

Here's the full error message:

selenium.common.exceptions.WebDriverException: Message: unknown error: Element ... is not clickable at point (621, 337). Other element would receive the click: ... (Session info: chrome=60.0.3112.90) (Driver info: chromedriver=2.26.436421 (6c1a3ab469ad86fd49c8d97ede4a6b96a49ca5f6),platform=Mac OS X 10.12.6 x86_64)

Here's the code I'm working with:

def wait_for_element_to_be_clickable(selector, timeout=10):
  global driver
  wd_wait = WebDriverWait(driver, timeout)

  wd_wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector)),
    'waiting for element to be clickable ' + selector)
  print ('WAITING')
  return driver.find_element_by_css_selector(selector)


""" custom clickable wait function that relies on exceptions. """
def custom_wait_clickable_and_click(selector, attempts=5):
  count = 0
  while count < attempts:
    try:
      wait(1)
      # This will throw an exception if it times out, which is what we want.
      # We only want to start trying to click it once we've confirmed that
      # selenium thinks it's visible and clickable.
      elem = wait_for_element_to_be_clickable(selector)
      elem.click()
      return elem

    except WebDriverException as e:
      if ('is not clickable at point' in str(e)):
        print('Retrying clicking on button.')
        count = count + 1
      else:
        raise e

  raise TimeoutException('custom_wait_clickable timed out')

CRX Extractor 從 Chrome 應用程式商店下載備份 .CRX 擴充功能

本文要介紹的「CRX Extractor」可幫你快速下載 Chrome 線上應用程式商店的擴充功能,只要將擴充功能網址貼上,立即取得 .CRX 原始檔,之後可隨時將 .CRX 拖曳到瀏覽器來安裝外掛,而不用受限於只能從 Chrome 應用程式商店來取得外掛。

此外,它還有另外一項功能,將 .CRX 上傳後可以取得原始碼!包括這個外掛完整檔案結構,對於要學習或研究開發來說是個非常棒的工具,也能透過檢查原始碼來查看 Chrome 外掛是否安全。

網站名稱:CRX Extractor
網站鏈結:http://crxextractor.com/

使用教學

開啟 CRX Extractor 網站後,點選「Let’s Start」開始後會有兩個功能,我們先從下載 Chrome 外掛檔案開始說明。如何下載或備份商店裡的擴充功能呢?很簡單,複製該 Google Chrome 擴充功能頁面的鏈結,把它複製、貼到 CRX Extractor 下載功能,點選「OK」就能取得 .CRX 檔。

CRX Extractor

下載的 .CRX 檔可以隨時安裝到 Google Chrome 瀏覽器,即使擴充功能商店已經把該外掛移除也沒問題!開啟擴充功能頁面(或在網址列輸入 chrome://extensions),把 .CRX 檔拖曳到瀏覽器就會出現安裝提示。

CRX Extractor

另一個 CRX Extractor 的功能是取得 Google Chrome 外掛原始碼!根據網站開發者所說,這項功能提供其他入門的外掛開發者一個學習、參考的渠道,尤其對於 Chrome 擴充功能完全沒有概念但又希望可以嘗試來開發外掛,以現有的原始碼作為參考似乎是個不錯的起點。

將外掛的 .CRX 檔案上傳(在 Get Source Code)下方,就能將它重新打包成壓縮檔。

CRX Extractor

下載後解壓縮,就會有外掛已經封包好的完整檔案,例如一些 html、json 或圖片檔。

CRX Extractor


How to open new tab in Chrome with Selenium-chromeDriver in Python

This works for chrome-

driver.execute_script("window.open('https://www.google.com');")

Python selenium —— 模拟鼠标键盘操作(ActionChains)

用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击、双击、点击鼠标右键、拖拽等等。而selenium给我们提供了一个类来处理这类事件 —— ActionChains
selenium.webdriver.common.action_chains.ActionChains(driver)
这个类基本能够满足我们所有对鼠标操作的需求。

1.ActionChains基本用法

首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。
这种情况下我们可以有两种调用方法:
  • 链式写法
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
  • 分步写法
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()
两种写法本质是一样的,ActionChains都会按照顺序执行所有的操作。

2.ActionChains方法列表

click(on_element=None) ——单击鼠标左键
click_and_hold(on_element=None) ——点击鼠标左键,不松开
context_click(on_element=None) ——点击鼠标右键
double_click(on_element=None) ——双击鼠标左键
drag_and_drop(source, target) ——拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开
key_down(value, element=None) ——按下某个键盘上的键
key_up(value, element=None) ——松开某个键
move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标
move_to_element(to_element) ——鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置
perform() ——执行链中的所有动作
release(on_element=None) ——在某个元素位置松开鼠标左键
send_keys(*keys_to_send) ——发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素
接下来用示例来详细说明和演示每一个方法的用法:

3.代码示例

1. 点击操作
示例网址http://sahitest.com/demo/clicks.htm
代码:
# -*- coding: utf-8 -*-

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


driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/clicks.htm')

click_btn = driver.find_element_by_xpath('//input[@value="click me"]')  # 单击按钮
doubleclick_btn = driver.find_element_by_xpath('//input[@value="dbl click me"]')  # 双击按钮
rightclick_btn = driver.find_element_by_xpath('//input[@value="right click me"]')  # 右键单击按钮


ActionChains(driver).click(click_btn).double_click(doubleclick_btn).context_click(rightclick_btn).perform()  # 链式用法

print driver.find_element_by_name('t2').get_attribute('value')

sleep(2)
driver.quit()
结果:
[CLICK][DOUBLE_CLICK][RIGHT_CLICK]
2.鼠标移动
示例网址http://sahitest.com/demo/mouseover.htm
示例代码:
# -*- coding: utf-8 -*-

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

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/mouseover.htm')

write = driver.find_element_by_xpath('//input[@value="Write on hover"]')  # 鼠标移动到此元素,在下面的input框中会显示“Mouse moved”
blank = driver.find_element_by_xpath('//input[@value="Blank on hover"]')  # 鼠标移动到此元素,会清空下面input框中的内容

result = driver.find_element_by_name('t1')

action = ActionChains(driver)
action.move_to_element(write).perform()  # 移动到write,显示“Mouse moved”
print result.get_attribute('value')

# action.move_to_element(blank).perform()
action.move_by_offset(10, 50).perform()  # 移动到距离当前位置(10,50)的点,与上句效果相同,移动到blank上,清空
print result.get_attribute('value')

action.move_to_element_with_offset(blank, 10, -40).perform()  # 移动到距离blank元素(10,-40)的点,可移动到write上
print result.get_attribute('value')

sleep(2)
driver.quit()
结果
Mouse moved

Mouse moved
一般很少用位置关系来移动鼠标,如果需要,可参考下面的链接来测量元素位置
http://jingyan.baidu.com/article/eb9f7b6d87e2ae869264e847.html
3.拖拽
示例网址http://sahitest.com/demo/dragDropMooTools.htm
代码:
# -*- coding: utf-8 -*-

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

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/dragDropMooTools.htm')

dragger = driver.find_element_by_id('dragger')  # 被拖拽元素
item1 = driver.find_element_by_xpath('//div[text()="Item 1"]')  # 目标元素1
item2 = driver.find_element_by_xpath('//div[text()="Item 2"]')  # 目标2
item3 = driver.find_element_by_xpath('//div[text()="Item 3"]')  # 目标3
item4 = driver.find_element_by_xpath('//div[text()="Item 4"]')  # 目标4

action = ActionChains(driver)
action.drag_and_drop(dragger, item1).perform()  # 1.移动dragger到目标1
sleep(2)
action.click_and_hold(dragger).release(item2).perform()  # 2.效果与上句相同,也能起到移动效果
sleep(2)
action.click_and_hold(dragger).move_to_element(item3).release().perform()  # 3.效果与上两句相同,也能起到移动的效果
sleep(2)
# action.drag_and_drop_by_offset(dragger, 400, 150).perform()  # 4.移动到指定坐标
action.click_and_hold(dragger).move_by_offset(400, 150).release().perform()  # 5.与上一句相同,移动到指定坐标
sleep(2)
driver.quit()
结果:
dropped dropped dropped dropped
一般用坐标定位很少,用上例中的方法1足够了,如果看源码,会发现方法2其实就是方法1中的drag_and_drop()的实现。注意:拖拽使用时注意加等待时间,有时会因为速度太快而失败。
4.按键
模拟按键有多种方法,能用win32api来实现,能用SendKeys来实现,也可以用selenium的WebElement对象的send_keys()方法来实现,这里ActionChains类也提供了几个模拟按键的方法。
示例网址http://sahitest.com/demo/keypress.htm
代码1:
# -*- coding: utf-8 -*-

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

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()
driver.get('http://sahitest.com/demo/keypress.htm')

key_up_radio = driver.find_element_by_id('r1')  # 监测按键升起
key_down_radio = driver.find_element_by_id('r2')  # 监测按键按下
key_press_radio = driver.find_element_by_id('r3')  # 监测按键按下升起

enter = driver.find_elements_by_xpath('//form[@name="f1"]/input')[1]  # 输入框
result = driver.find_elements_by_xpath('//form[@name="f1"]/input')[0]  # 监测结果

# 监测key_down
key_down_radio.click()
ActionChains(driver).key_down(Keys.CONTROL, enter).key_up(Keys.CONTROL).perform()
print result.get_attribute('value')

# 监测key_up
key_up_radio.click()
enter.click()
ActionChains(driver).key_down(Keys.SHIFT).key_up(Keys.SHIFT).perform()
print result.get_attribute('value')

# 监测key_press
key_press_radio.click()
enter.click()
ActionChains(driver).send_keys('a').perform()
print result.get_attribute('value')
driver.quit()
结果:
key downed charCode=[0] keyCode=[17] CTRL
key upped charCode=[0] keyCode=[16] NONE
key pressed charCode=[97] keyCode=[0] NONE
示例2:
示例网址http://sahitest.com/demo/label.htm
代码:
# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from time import sleep

driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.maximize_window()

driver.get('http://sahitest.com/demo/label.htm')

input1 = driver.find_elements_by_tag_name('input')[3]
input2 = driver.find_elements_by_tag_name('input')[4]

action = ActionChains(driver)
input1.click()
action.send_keys('Test Keys').perform()
action.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform()  # ctrl+a
action.key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()  # ctrl+c

action.key_down(Keys.CONTROL, input2).send_keys('v').key_up(Keys.CONTROL).perform()  # ctrl+v

print input1.get_attribute('value')
print input2.get_attribute('value')

driver.quit()
结果:
Test Keys
Test Keys
复制粘贴用WebElement< input >.send_keys()也能实现,大家可以试一下,也可以用更底层的方法,同时也是os弹框的处理办法之一的win32api,有兴趣也可以试试SendKeyskeybd_event

from : https://huilansame.github.io/huilansame.github.io/archivers/mouse-and-keyboard-actionchains