背景

上次支付宝沙龙分享了基于 appium 的自动遍历小工具, 有些朋友感兴趣, 想看下代码,
为了给大家一个参考, 我这里贴部分的关键算法代码给大家吧
这份代码写的很挫, 功能也很简单, 只是个演示 demo, 是为了证明 appium can do IT.
我计划用 Java 重构, 这个只当是参考吧

部分代码参考

def capabilities
    {
        'browserName' => '',
        'device' => 'android',
        'version' => '4.1',
        'app-activity'=> 'com.taobao.tao.Welcome',
        'app-package'=> 'com.taobao.taobao'
        #'app-activity'=> '.activity.MainActivity',
        #'app-package'=> 'com.sankuai.meituan'
    }
end

def setup
    server_url = 'http://127.0.0.1:4723/wd/hub'
    @driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => server_url)
    @driver.manage.timeouts.implicit_wait = 30 # seconds
    puts 'sleep 20'
    sleep 20
    @driver
end
def config()
    @config={}
    @config['blacklist']=['立即抢购', '美团承诺 团购无忧', '退款']
end

def refresh()
    root=[]
    el_array=@driver.find_elements(:xpath, "//text[@clickable=true]")
    #如果点击没有发生变化, 就跳过
    if el_array.size==@list.size
        return @list
    end
    el_array.each do |node|
        begin
            text=node.text
            location=node.location
            is_skip=false
            next if text.strip==''
            next if text.size<2
            @config['blacklist'].each do |keyword|
                if text.index(keyword)
                    is_skip=true
                    break
                end
            end
            next if is_skip
            current={}
            current['click']=false
            #位置相差不大 也认为是相同
            current['sign']=text+'|'+location.x.to_s[0..1]
            current['text']=text
            current['object']=node
            root << current
        rescue Exception=>e
            puts e.message
        end
    end
    root
end
def find_return_root(el)
    current=nil
    @nodes.each do |node|
        if node.content['sign']==el['sign']
            current=node
            break
        end
    end
    current=current.parent if current
    return(current)
end
def travel()
    @list||=[]
    @nodes ||= Tree::TreeNode.new("ROOT", {})
    @current||=@nodes
    @index||=0
    @index+=1
    @list=refresh()
    has_new=false
    return_root=nil
    @list.each do |el|
        #判断是否曾经出现过
        return_root=find_return_root(el)
        if return_root==nil
            has_new=true
            #如果是新元素, 就添加到tree中
            @current << Tree::TreeNode.new(el['sign'], el)
        end
    end
    #如果没有新元素, 代表回到某个父节点
    if has_new==false
        @current=return_root
    end
    save()
    if @current.level>7
        @driver.navigate.back
        travel()
    end

    #从未被点击的地方点击
    current=nil
    @current.children.each do |child|
        if child.content['click']==false
            current=child   
            @list.each do |node|
                if node['sign']==current.content['sign']
                    current.content['click']=true
                    @current=current
                    node['object'].click
                    sleep 3
                    travel()
                    break
                end
            end
            break               
        end
    end
    if current==nil
        @driver.navigate.back
        travel()
    end
end

运行结果

因为这次采用的是 uiautomator, 代码也优化, 所以执行时间很长
跑十几分钟, 手机就因为锁屏失败, 所以针对淘宝 app, 我一直没跑全过, 生成的思维导图只是淘宝部分栏目的浅层结构图 想跑全的话, 就自己修改手机, 或者用虚拟机吧
如下是生成的结果:

计划

我接下来, 我在做上次分享的 ppt 最后一页的事情, 我想基于这个搞个在线服务. 有实力感兴趣的同学可以报名参加.
主要是为第三方的企业提供 app 遍历和附加服务. 一个实验性的技术项目.
目标

  1. 优化速度
  2. 优化算法, 解决回环
  3. 自动生成 appium 的自动化代码
  4. 支持规则
  5. 从 ruby 转到 java 上去实现
  6. 做个服务网站
  7. 支持 dom diff 和灰度对比

捐助论坛

论坛服务器有成本, 我们希望为 TesterHome 挣点云服务器费用.
捐助论坛超过 100 元的同学或论坛精华帖超过 10 个的同学可得到全部的代码, ppt 和演示用例
论坛创始人是@lihuazhang 恒温同学, 真名张立华.
我们的支付宝官方账号: testerhome@126.com
支付宝收款地址: https://me.alipay.com/testerhome

TesterHome支付宝


↙↙↙阅读原文可查看相关链接,并与作者交流