• 定向班_答疑_20191218 at December 18, 2019

    可能是bug:
    appcrawler2.4版本,在不同APP上均出现这个问题: 第4个tab遍历不到,第5个可以(应该点击第4个的时候,会去点击第一个)

  • 定向班_答疑_20191218 at December 18, 2019

    appcrawler遍历结束后如何强制退出?

    我用的2.4.0,遍历结束后会尝试多次navigation back,而不是直接退出。

    1. 可能某些APP并不是通过navigate back退出。
    2. 可能遍历的初始页面不是首页,navigate back会进入别的页面。
  • 作业1: 搭建STF

  • 遍历了行情页的所有tab下的所有元素。
    深度为1.
    tagLimitMax为4.

    pluginList: []
    saveScreen: true
    reportTitle: ""
    resultDir: ""
    waitLoading: 500
    waitLaunch: 6000
    showCancel: true
    maxTime: 10800
    maxDepth: 1

    capability:
    noReset: "true"
    fullReset: "false"
    appium: "http://127.0.0.1:4723/wd/hub"
    appPackage: com.xueqiu.android
    appActivity: .view.WelcomeActivityAlias
    testcase:
    name: "TesterHome AppCrawler"
    steps: []

    selectedList:
    - xpath: "//*[@resource-id='com.xueqiu.android:id/mainContent']//*[@clickable='true' and @resource-id!='']"
    - xpath: "//*[@resource-id='com.xueqiu.android:id/mainContent']//*[@clickable='true']//*[@resource-id!='' or @text!=''][1]"

    firstList: []
    lastList:
    # 倒数第二遍历 沪深/科创 等二级tab
    - xpath: "//*[@resource-id='com.xueqiu.android:id/indicator_with_shadow']//*"
    # 最后再遍历 基金/股票 tab
    - xpath: "//*[@resource-id='com.xueqiu.android:id/quotes_center_nav_bar']//*"

    backButton:
    - given: []
    when: null
    then: []
    xpath: "Navigate up"
    action: ""
    actions: []
    times: 0
    triggerActions:
    # 只要发现行情tab没被选中,就选中它
    - xpath: "//*[@text='行情' and @selected='false']"
    action: "click"
    times: 0

    xpathAttributes:
    - "name"
    - "label"
    - "value"
    - "resource-id"
    - "content-desc"
    - "instance"
    - "text"
    sortByAttribute:
    - "depth"
    - "list"
    - "selected"

    #findBy: "default"
    findBy: "xpath"

    defineUrl: []
    # 为了让深度更明确,暂不自定义url
    # - //*[@resource-id="com.xueqiu.android:id/page_type_stock"]
    # - //*[@resource-id="com.xueqiu.android:id/page_type_fund"]

    baseUrl: []
    appWhiteList: []
    urlBlackList: []
    urlWhiteList: []
    blackList:
    - xpath: ".*[0-9]{2}.*"
    # 不遍历搜索和消息功能
    - xpath: "//*[@resource-id='com.xueqiu.android:id/action_message']"
    - xpath: "//*[@resource-id='com.xueqiu.android:id/action_search']"

    beforeRestart: []
    beforeElement:
    - given: []
    when: null
    then: []
    xpath: "/*"
    action: "Thread.sleep(100)"
    actions: []
    times: 0
    afterElement: []
    afterPage: []
    afterPageMax: 2
    tagLimitMax: 4
    tagLimit: []
    assertGlobal: []

  • action改成click


  • 课后作业

    package org.openqa.selenium.chrome;

    import org.junit.Test;
    import org.mockito.Mockito;

    import static org.hamcrest.CoreMatchers.equalTo;
    import static org.junit.Assert.assertThat;

    public class ChromeDriverInfoTest {

    private ChromeDriverInfo driverInfo = new ChromeDriverInfo();

    @Test
    public void getDisplayName() {
    String name = driverInfo.getDisplayName();
    assertThat(name, equalTo("Chrome"));
    }

    @Test
    public void isSupporting() {
    ChromeOptions mockCap = Mockito.mock(ChromeOptions.class);
    //TODO
    //2.23之后的mockito会报错: Mockito can only mock non-private & non-final classes.
    //将mockito设定为 2.23.0,可正常运行. 原因未知.
    Mockito.when(mockCap.getBrowserName()).thenReturn("");
    Mockito.when(mockCap.getCapability(Mockito.anyString())).thenReturn(null);
    assertThat(driverInfo.isSupporting(mockCap), equalTo(false));


    Mockito.when(mockCap.getBrowserName()).thenReturn("chrome");
    assertThat(driverInfo.isSupporting(mockCap), equalTo(true));

    Mockito.when(mockCap.getBrowserName()).thenReturn("");
    Mockito.when(mockCap.getCapability("chromeOptions")).thenReturn("");
    assertThat(driverInfo.isSupporting(mockCap), equalTo(true));

    Mockito.when(mockCap.getCapability(Mockito.anyString())).thenReturn(null);
    Mockito.when(mockCap.getCapability("goog:chromeOptions")).thenReturn("");
    assertThat(driverInfo.isSupporting(mockCap), equalTo(true));
    }

    }

  • http://47.95.238.18:10080/ricky/homework/-/network/master

    1) init master/release/develop

    git init
    git add .
    git commit -m "init"
    git push

    # release
    git checkout -b release
    git push -u origin release
    # set protection on gitlab

    # develop
    git checkout -b develop
    # edit
    git commit -a -m "dev1"
    # edit
    git commit -a -m "dev2"
    # push
    git push -u origin develop

    # mr develop to release on gitlab
    # mr release to master on gitlab
    # tag 1.0

    2) feature 1

    git checkout develop
    git checkout -b feature_login_20190921
    # edit
    git commit -a -m "f_login_1"
    # edit
    git commit -a -m "f_login_2"
    # merge dev to feature
    git merge develop
    # fix conflicts
    git commit -a -m "merge dev to feature; fix conflicts"
    git push -u feature_login_20190921

    3) release 2

    git checkout develop
    # merge feature_login to develop (conflicts have been fixed on step2)
    git merge feature_login_20190921
    git push develop

    # mr develop to release on gitlab

    4) more features

    git checkout develop
    git checkout -b feature_order_20190921

  • 作业1

    p=20444
    top -b -p $p -n 20 -d 1 | grep --line-buffered -E "^ +$p" \
    | awk 'BEGIN{print("cpu","mem")}\
    { print $9,$10;cpu+=$9;mem+=$10 }\
    END{ print("---");if(NR>0){print(cpu/NR,mem/NR)} }'

    课后作业

    page_source(){
    adb shell "uiautomator dump --compressed && cat /sdcard/window_dump.xml"
    }

    inspect(){
    page_source \
    | sed -E 's#>#>\n#g' \
    | awk -F "\"" -v indent=0 \
    '{\
    offset=0;\
    if ($1~/^ *<node /) {\
    if ($1~/NAF=$/) {\
    offset=2;\
    }\
    text=$(offset+4);\
    r_id=$(offset+6);\
    bounds=$(offset+34);\
    if (text!~/^$/||r_id!~/^$/) {\
    for (i=0;i<indent;i++){\
    printf("--");\
    }\
    text=substr(text,1,10);\
    location_len=index(bounds,"][");\
    location=substr(bounds,1,location_len);\
    printf(" resource-id=\"%s\" text=\"%s\" location=\"%s\"\n",r_id,text,location);\
    }\
    \
    if ($0~/[^\/]> *$/) {\
    indent+=1;\
    }\
    } else if ($1~/^ *<\/node>/) {\
    indent-=1;\
    }\
    }'
    }

    说明:

    1. dump
    2. 用sed拆分行(从>后面拆分)
    3. awk: 用引号作为分隔符(因为text和content-desc中可能有空格,不好处理)
    4. awk: 遇到有NAF的行,需要对指针做个偏移
    5. awk: 遇到标签未闭合的行$0~/[^\/]> *$/,说明下一个节点是子节点,需要增加一个缩进
    6. awk: 遇到</node>, 说明下一个节点辈分+1,需要恢复一个缩进
    7. awk: 遇到符合条件的节点text !~ /^$/ || r_id !~ /^$/,输出id/text/location

    注意:
    text或content-desc中有可能出现text= resource-id= bounds=等字符串;不可能出现" < >等字符。

  • AWK 学习笔记和心得 at September 10, 2019

    👍 很有参考价值,感谢