通用技术 UI 自动化高亮元素与截图小工具

0x7C00 · 2017年03月20日 · 最后由 未更新 回复于 2018年09月04日 · 2783 次阅读
本帖已被设为精华帖!

做 UI 自动化时,写了 2 个方法,方便清晰辨识定位的元素 and 保留定位证据,与大家分享下。

  • 高亮元素

def highlight(func):

    def apply_style(element):
                # 实现的方式很简单,就是定位到元素后,执行js样式
        driver.execute_script("arguments[0].style.border='6px solid red'", element)

    @wraps(func)
    def wrapper(self, *args, **kwargs):
        element = func(self, *args, **kwargs)
        apply_style(element)
        return element

    return wrapper


  • 截图定位的元素

def screenshot(func):

    def screen_shot(screen_name):
        driver.save_screenshot(screen_name)

    @wraps(func)
    def wrapper(self, *args, **kwargs):
        element = func(self, *args, **kwargs)

        screen_shot(str(args[-1]) + '.jpg') # 默认是以定位元素属性为文件名
        return element


    return wrapper

  • 使用
class Action(object):
    def __init__(self, driver):
        self.driver = driver

    @screenshot
    @highlight
    def find_element(self, *loc):
        try:
            WebDriverWait(self.driver, 15).until(lambda driver: driver.find_element(*loc).is_displayed())
            return self.driver.find_element(*loc)
        except Exception as e:
            return e

  • 测试 (体现百度价值的时候到了.)

driver = webdriver.Chrome()

driver.get('http://www.baidu.com')

action = Action(driver)

action.find_element(By.ID, 'su')
time.sleep(3)
driver.quit()

  • 效果图 (su.jpg) 效果图(su.jpg)

  • 如果没封装一层定位方法,可以使用如下方式,稍微和上面有些不同,该方法会在定位前后截图,可以用来对比。
def highlight(element, element_name=None, debug=True):
        '''
        :param element:定位到的元素对象
        :param debug:开关截图功能,默认为True开启截图功能
        :param element_name: 截图保存图片的名字,不传时,默认用before after作为图片名
        '''
    # 高亮元素
    def apply_style():
        driver.execute_script("arguments[0].style.border='6px solid red'", element)

    # 截图
    def screen_shot(screen_name):
        driver.save_screenshot(screen_name)

    if debug:
        try:
            screen_shot(str(element_name) + '_before.jpg')
            apply_style()
            screen_shot(str(element_name) + '_after.jpg')
        except Exception as e:
            return e

    apply_style()

#  使用也很简单
element = driver.find_element(By.ID, 'kw')
highlight(element, 'kw')

还有可以改进的地方,就这些,希望对你有帮助。O(∩_∩) O

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 26 条回复 时间 点赞

实际测试中应该是要能高亮定位失败的元素才真的有用吧,既然元素已经定位到高亮有何意义呢

谢谢分享,特别是高亮元素那里

@lose 😊

@seveniruby 谢谢思寒加精。✨

0x7C00 回复

优秀就来自于每一天的改进和创新,值得鼓励和肯定

不错啊,谢谢分享

这个东西很赞,正好需要

高亮很赞

@lbxoqy 不客气.😀

学到了,谢谢

Traceback (most recent call last):
File "E:\test\test02.py", line 55, in
action.find_element(By.ID, 'su')
NameError: name 'By' is not defined
@xie_0723 您好!按照您提供的代码出现了异常,请问如何解决?

from selenium.webdriver.common.by import By

@bao_han 好的,谢谢。

求问!单用截图可行,但加上 highlight 功能时会报如下错!

0x7C00 #16 · 2017年04月18日 Author

@chestnut

你上面使用的 highlight 装饰器需要被装饰的函数 return 一个有效的 element 参数。你的 test_2 函数并没有 return 有效值。

建议你可以用最下面的 highlight 方法,定位到元素之后返回该元素,然后把定位到 element 传给 highlight 函数,就可以高亮了。

你好,楼主,这是用什么语言写的呢?支持 java 吗?

0x7C00 回复

你好,楼主!
但同样都是 return element,为什么 screenshot 能编译通过呢?是否说明 element 是有效的?
而且这种方式调用起来不如第一种方便

0x7C00 #20 · 2017年04月18日 Author

@chestnut 因为 screenshot 装饰器并不需要被装饰的函数有返回值传递给他。

都有 return element 是因为本身装饰的函数 find_element 需要 return element。

Python 装饰器本身的作用就是在被包装的函数前 or 后 or 前后做一个前置后置的处理动作。

  • 简单一句话就是 highlight 需要被装饰的函数有返回值,而 screenshot 不需要。
  • 你最后看到都有 return element 是 因为本身被装饰的 find_element 方法需要。
  • 可以多了解下装饰器,这样更容易使用。

你觉得不方便,是因为 test_2 函数中并没有额外封装的 find_element 方法。

如果统一封装定位的方法,然后再装饰使用,那之后,所有的定位元素高亮就很方便了。

0x7C00 #19 · 2017年04月18日 Author
刘扬 回复

@Allen_ Python 。你说的支持是什么意思啊?是直接用在 java 里边嘛?还是借鉴 Python 的这个写法?我想应该是后者把?不可以直接用在 java 中的噢,但是你可以使用 java 语言实现。我对 java 不熟悉,你可以 google 下。

0x7C00 回复

你好!用的后面的方法还是同样的错误 not yet implement
用的 appium1.4.16.1,google 了下 appium+driver.execute_script("arguments[0].style.border='6px solid red'", element) 关键词没有太多结果,有试过在 appium 上用这个方法么?看亲用的应该是 selenium 吧,会不会是 appium 不支持

有啥好办法只截高亮部分的图

0x7C00 #23 · 2017年04月28日 Author

hi,@yuweixx

好像没有直接的 API 用于部分截图。一般是借助于第三方的工具。例如 PIL

参考方法:

from selenium import webdriver
from PIL import Image

fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')

# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()

im = Image.open('screenshot.png') # uses PIL library to open image in memory

left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']


im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image

参考链接

mark,不错的文章

这个高亮定位的意义是啥?没有看明白,是我们跑自动脚本时,页面上会高亮显示?

0x7C00 #14 · 2017年03月22日 Author

@xlth1947 不客气😀

思寒_seveniruby 将本帖设为了精华贴 03月21日 00:53

很赞,学习了。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册