Advanced interaction of selenium web controls

Action

ActionChains: Execute mouse click, double click, right click, drag and other events on the PC side
TouchActions: Simulate PC and mobile side click, slide, drag, multi-touch and other gesture operations

Action Chains ActionChains

Execution principle:
When the ActionChains method is called, it will not be executed immediately, but all the operations will be put into a queue. When the perform() method is called, the events in the queue will be executed sequentially

Basic usage:

  • Generate an action actions =ActionChains(driver)
  • Action adding method 1 actions.move_to_element(menu)
  • Action adding method 2 actions.click(hidden_submenu)
  • Call the actions.perform() method to execute

Specific writing:

  • chain writing
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
  • Distribution writing
actions =ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()

ActionChains specific usage

Usage 1: click, right click, double click

actions =ActionChains(driver)
actions.click(element)
actions.double_click(element)
actions.context_click(element)
actions.perform()

Test site:  Clicks

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File        :test_02.py
@Describe    :
@Create      :2021/06/23 00:16:26
@Author      :od
'''
import pytest
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains


class TestActions:
    def setup(self):
        self.chrome_options = Options()
        self.chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")  # 指定配置好的 chrom
        self.chrome_driver = r"./chromedriver.exe"  # 驱动路径
        self.driver = webdriver.Chrome(self.chrome_driver, chrome_options=self.chrome_options)  # 加入驱动设置
        # self.driver.get('https://sahitest.com/demo/clicks.htm')  # 发起请求
        # self.driver.maximize_window()  # 设置为最大化
        self.driver.implicitly_wait(3)  # 添加一个隐式等待默认等待3秒

    def teardown(self):
        print('关闭浏览器')
        time.sleep(1)
        # self.driver.quit()

    # 测试用例如果不加sleep的话,元素如果没加载出来,是会报错的,所以我们要加个隐式等待
    def test_clicks(self):
        print('go')
        dbl_click_me = self.driver.find_element_by_xpath("//input[@value='dbl click me']")  # 双击
        click_me = self.driver.find_element_by_xpath("//input[@value='click me']")  # 单击
        right_me = self.driver.find_element_by_xpath("// input[ @ value='right click me']")  # 右键
        action = ActionChains(self.driver)  # 初始化
        action.click(click_me)  # 点击一次
        action.double_click(dbl_click_me)  # 双击两次
        action.context_click(right_me)  # 右键一次
        action.perform()  # 启动


if __name__ == '__main__':
    pytest.main(['-vs', "test_action.py::TestActions"])

Usage 2

Move the mouse over an element

action = ActionChains(self.driver)
action.move_to_element(element)
action.perform()

Add a mobile test case, the test URL is Baidu. Move the mouse to Baidu's settings, and a drop-down box will appear

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import pytest
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains


class TestActions:
    def setup(self):
        self.chrome_options = Options()
        self.chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")  # 指定配置好的 chrom
        self.chrome_driver = r"./chromedriver.exe"  # 驱动路径
        self.driver = webdriver.Chrome(self.chrome_driver, chrome_options=self.chrome_options)  # 加入驱动设置
        # self.driver.get('https://sahitest.com/demo/clicks.htm')  # 发起请求
        # self.driver.maximize_window()  # 设置为最大化
        self.driver.implicitly_wait(3)  # 添加一个隐式等待默认等待3秒

    def teardown(self):
        print('关闭浏览器')
        time.sleep(1)
        # self.driver.quit()

    # 测试用例如果不加sleep的话,元素如果没加载出来,是会报错的,所以我们要加个隐式等待
    @pytest.mark.skip  # 不想执行这个测试用例可以加这个装饰器跳过
    def test_clicks(self):
        print('go')
        dbl_click_me = self.driver.find_element_by_xpath("//input[@value='dbl click me']")  # 双击
        click_me = self.driver.find_element_by_xpath("//input[@value='click me']")  # 单击
        right_me = self.driver.find_element_by_xpath("// input[ @ value='right click me']")  # 右键
        action = ActionChains(self.driver)  # 初始化
        action.click(click_me)  # 点击一次
        action.double_click(dbl_click_me)  # 双击两次
        action.context_click(right_me)  # 右键一次
        action.perform()  # 启动

    def test_movie(self):
        self.driver.get('https://www.baidu.com/')  # 发起请求
        move_mouse = self.driver.find_element_by_xpath("//span[@id='s-usersetting-top']")  # 定位移动u元素
        action = ActionChains(self.driver)  # 初始化
        action.move_to_element(move_mouse)   # 移动光到设置去
        action.perform()  # 启动


if __name__ == '__main__':
    pytest.main(['-vs', "test_action.py::TestActions"])

The URL for testing demo 2 is:  Mootools Drag and Drop Example

The code is roughly the same as above, add a decorator that skips Baidu, and then add a method test_move2 below to perform a drag and drop

   def test_movie2(self):
        self.driver.get('https://sahitest.com/demo/dragDropMooTools.htm')  # 发起请求
        drag_element = self.driver.find_element_by_xpath('//*[@id="dragger"]')  # 拿起元素
        drop_element1 = self.driver.find_element_by_xpath("/html/body/div[2]")  # 放下元素
        drop_element2 = self.driver.find_element_by_xpath('/html/body/div[3]')  # 放下元素
        drop_element3 = self.driver.find_element_by_xpath("/html/body/div[4]")  # 放下元素
        drop_element4 = self.driver.find_element_by_xpath("/html/body/div[5]")  # 放下元素
        action = ActionChains(self.driver)  # 初始化
        action.drag_and_drop(drag_element, drop_element1).drag_and_drop(drag_element, drop_element2).drag_and_drop(drag_element, drop_element3).drag_and_drop(drag_element,   
        drop_element4).perform() #链式写法perform

However, if you write like this, there will be a situation

I checked a lot of posts, and I don’t know why this happened. There is a vague answer that is

Because the action of ActionChains is added to a list, repeated use may cause some unpredictable problems

Therefore, it is best to rewrite the example action every time you encounter a situation where you don’t understand, and rewrite it as follows

    def test_movie2(self):
        self.driver.get('https://sahitest.com/demo/dragDropMooTools.htm')  # 发起请求
        drag_element = self.driver.find_element_by_xpath('//*[@id="dragger"]')  # 拿起元素
        drop_element1 = self.driver.find_element_by_xpath("/html/body/div[2]")  # 放下元素
        drop_element2 = self.driver.find_element_by_xpath('/html/body/div[3]')  # 放下元素
        drop_element3 = self.driver.find_element_by_xpath("/html/body/div[4]")  # 放下元素
        drop_element4 = self.driver.find_element_by_xpath("/html/body/div[5]")  # 放下元素
        action = ActionChains(self.driver)  # 初始化
        action.drag_and_drop(drag_element, drop_element1).perform()
        time.sleep(1)
        action2 = ActionChains(self.driver)  # 初始化
        action2.drag_and_drop(drag_element, drop_element2).perform()
        time.sleep(1)
        action3 = ActionChains(self.driver)  # 初始化
        action3.drag_and_drop(drag_element, drop_element3).perform()
        time.sleep(1)
        action4 = ActionChains(self.driver)  # 初始化
        action4.drag_and_drop(drag_element, drop_element4).perform()

Change three. . . It is found that there is no problem of pause time. . . The following code is also possible

def test_movie2(self):
        self.driver.get('https://sahitest.com/demo/dragDropMooTools.htm')  # 发起请求
        drag_element = self.driver.find_element_by_xpath('//*[@id="dragger"]')  # 拿起元素
        drop_element1 = self.driver.find_element_by_xpath("/html/body/div[2]")  # 放下元素
        drop_element2 = self.driver.find_element_by_xpath('/html/body/div[3]')  # 放下元素
        drop_element3 = self.driver.find_element_by_xpath("/html/body/div[4]")  # 放下元素
        drop_element4 = self.driver.find_element_by_xpath("/html/body/div[5]")  # 放下元素
        action = ActionChains(self.driver)  # 初始化
        action.drag_and_drop(drag_element, drop_element1).pause(1).drag_and_drop(drag_element, drop_element2).pause(1).drag_and_drop(drag_element, drop_element3).pause(1).drag_and_drop(drag_element, drop_element4).pause(1).perform() # pause(1) 代表暂停1秒

usage three

Use ActionChains to simulate keypress methods. The usage is as follows

action = ActionChains(self.driver)
action.send_keys(Keys.BACK_SPACE)
# 或者action.key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL)
action.perform()

Test URL:  Label

Test effect,
1. Fill in lakes james in the first Username,
2. Select all in the second input box, copy and paste it into the input box

def test_movie3(self):
        url = 'https://sahitest.com/demo/label.htm'
        usernames = 'lakes'
        passwds = 'james'
        self.driver.get(url)  # 发起请求
        click_element = self.driver.find_element_by_xpath("//label[contains(text(),'Username')]//input[@type='textbox']")  # 选中第一个框
        second_element = self.driver.find_element_by_xpath("/html/body/label[2]/table/tbody/tr/td[2]/input")
        action = ActionChains(self.driver)
        action.click(click_element).pause(1).send_keys(usernames).pause(0.5).send_keys(Keys.SPACE).pause(1).send_keys(f'{passwds}').pause(1).send_keys(        Keys.BACK_SPACE).pause(1).key_down(Keys.CONTROL).send_keys('a').pause(1).key_down(Keys.CONTROL).send_keys('c').pause(2).click(second_element).pause(1).key_down(Keys.CONTROL).send_keys('v').perform()
          # 1、点击第一个元素然后等待1秒然后发送username和空格然后发送密码过去然后发送一个删除1个字母,然后全选然后点击复制,然后点击第二个元素,然后粘贴上去
          # 2、ctrl + a 不能通过 action.send_keys(Keys.CONTROL, "a") 直接发送,需要 key_down之后再 send_keys再然后 key_up(Keys.CONTROL)

Common methods for keyboard operations of the Keys class:

Keys 类键盘操作的常用方法:
引入Keys类:
    from selenium.webdriver.common.keys import Keys
常用方法:
  send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
  send_keys(Keys.SPACE)  空格键(Space)
  send_keys(Keys.TAB)  制表键(Tab)
  send_keys(Keys.ESCAPE)  回退键(Esc)
  send_keys(Keys.ENTER) 回车键(Enter)
  send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)
  send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)
  send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
  send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)
...
#输入框输入内容
driver.find_element_by_id("kw1").send_keys("seleniumm")
time.sleep(3)
#删除多输入的一个m
driver.find_element_by_id("kw1").send_keys(Keys.BACK_SPACE)
time.sleep(3)
...

TouchAction usage

ActionChains and TouchAction can be used to simulate events such as clicks, double-clicks, and slides. ActionChains are used to execute events such as mouse movement, keypress, and drag on the PC side; TouchActions are similar to ActionChains in usage, and can be used to simulate gesture operations such as clicking, sliding, and dragging on PC and mobile terminals.


Both ActionChains and TouchAction store actions in the queue, and then execute the perform() method to execute the actions in the order of the queue.

Gesture Control Method

double_tap 双击
flick 滑动
flick_element 从某个元素位置开始滑动
long_press 长按
move 手势移动指定偏移
Perform 执行
release 释放手势
scroll 点击并滚动
scroll_from_element 从某个元素位置开始手势点击并滚动(向下滑动为负数,向上滑动为正数)
flick_element——从某个元素位置开始手势滑动(负数:向上滑动,正数:向下滑动)
tap 在指定元素上点击
tap_and_hold 在指定元素上点击但不释放

Example: Open Baidu search and search for the Lakers, pull down and slide to the end

from selenium.webdriver import TouchActions

def test_serarch(self):
        url = 'https://www.baidu.com/'
        kw = '湖人'
        self.driver.get(url)  # 发起请求
        input_element = self.driver.find_element_by_xpath("//input[@id='kw']")  # 选中输入框
        input_element.send_keys(kw)  # 对选中的输入文字
        search = self.driver.find_element_by_id("su")  # 点击搜索
        action = TouchActions(self.driver)  # 初始化一个action
        action.tap(search).perform()  # 点击确认等待2秒之后执行, 并执行
        action.scroll_from_element(input_element, 0, 10000).perform()  # 传入三个元素。第一个元素是选定的起点,x,y 是滚动的偏移量

But it will report an error, so we have to fix it when initializing

def setup(self):
        self.chrome_options = Options()
        self.chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")  # 指定配置好的 chrom
        self.chrome_options.add_experimental_option("w3c", False) # 设置为w3c
        self.chrome_driver = r"./chromedriver.exe"  # 驱动路径
        self.driver = webdriver.Chrome(self.chrome_driver, chrome_options=self.chrome_options)  # 加入驱动设置
        # self.driver.get('https://sahitest.com/demo/clicks.htm')  # 发起请求
        # self.driver.maximize_window()  # 设置为最大化
        self.driver.implicitly_wait(3)  # 添加一个隐式等待默认等待3秒

    def teardown(self):
        print('关闭浏览器')
        # time.sleep(1)

Finally: If you don’t want to experience the feeling of not being able to find information when learning, no one answering questions, and giving up after persisting for a few days, here I will share with you some learning resources for automated testing, hoping to give you some guidance on the way forward. Come to help, friends can get it for free if they need it 【保证100%免费】

Collection of software testing interview questions

Our advanced study of automated testing must be to find a high-paying job. The following interview questions are the latest interview materials from first-line Internet companies such as Ali, Tencent, and Byte, and some Byte bosses have given authoritative answers. After completing this set of interview materials, I believe everyone can find a satisfactory job.

How to get the video file:

Guess you like

Origin blog.csdn.net/m0_75277660/article/details/130624918