最新消息:20210917 已从crifan.com换到crifan.org

【已解决】iOS自动化处理WiFi代理:WiFi详情页中更新代理配置信息

代理 crifan 398浏览 0评论
折腾:
【未解决】iOS自动化安装app:给当前WiFi去掉代理以及自动安装app后再恢复之前代理
期间,根据之前的
【未解决】iOS自动化处理WiFi代理:配置代理页中从关闭切换到手动恢复之前代理配置信息
的思路,决定直接去实现:
在当去WiFi详情页,去支持 update 代理的情况。
如果实现了,则自动支持:
关闭之前手动代理,且返回手动代理信息
从关闭 去恢复之前的手动代理信息
此处实现期间,觉得之前太繁琐了,所以改为:
输入新的代理 和 返回旧的代理,都改为这种更清晰:
(1)关闭
{
    type: 关闭
    value: None
}
(2)手动
{
    type: 手动
    value
        server
        port
        authenticate
}
(3)自动
{
    type: 自动
    value:
        url
}
简洁明了。
其中本来还打算给type定义成enum,需要引入额外定义,觉得太麻烦,所以放弃了。
继续去实现
期间需要去单独看看,本身之前如果代理是 自动时,url的值是什么
因为此处:
<XCUIElementTypeTextField type="XCUIElementTypeTextField" name="URL" label="URL" enabled="true" visible="true" x="72" y="281" width="314" height="21"/>
没有value值
故意去加了auto的url值
xml
<XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
    <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="your_auto_proxy_url" name="URL" label="URL" enabled="true" visible="true" x="72" y="281" width="314" height="21"/>
    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="313" width="414" height="2"/>
    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
</XCUIElementTypeCell>
很明显,有value值了。
另外,对于switch
                    <XCUIElementTypeCell type="XCUIElementTypeCell" value="0" enabled="true" visible="true" x="0" y="359" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="404" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="鉴定" name="鉴定" label="鉴定" enabled="true" visible="true" x="20" y="359" width="323" height="46"/>
                        <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="0" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
                    </XCUIElementTypeCell>
要去搞清楚:如何输入值
突然想到了:直接点击,即可。
写了半天,代码是:
    # def iOSRestoreWiFiProxy(self, previousProxyInfo):
    # def iOSDisableWiFiProxy(self):
    def iOSProxyConfigUpdateProxy(self, newProxyInfo=None):
        """in proxy config = 代理配置 page, update proxy type


        Args:
            newProxyInfo (dict): new proxy info
        Returns:
            bool, dict/str
                True, old proxy config info
                False, error message str
        Raises:
        """
        isUpdateOk = False
        respInfo = None
        
        # check current proxy type: 手动/自动/关闭
        curPageXml = self.get_page_source()
        soup = CommonUtils.xmlToSoup(curPageXml)
        morenInfoChainList = [
            {
                "tag": "XCUIElementTypeTable",
                "attrs": self.FullScreenAttrDict
            },
            {
                "tag": "XCUIElementTypeCell",
                "attrs": {"enabled":"true", "visible":"true", "x":"0", "width":"%s" % self.X}
            },
            {
                "tag": "XCUIElementTypeButton",
                # "attrs": {"enabled":"false", "visible":"true", "name": "更多信息"}
                "attrs": {"visible":"true", "name": "更多信息"}
            },
        ]
        morenInfoSoup = CommonUtils.bsChainFind(soup, morenInfoChainList)
        if not morenInfoSoup:
            respInfo = "Fail to find 更多信息 in config proxy page"
            return isUpdateOk, respInfo


        parentCellSoup = morenInfoSoup.parent
        curTypeName = self.iOSFindChildProxyType(parentCellSoup)
        if not curTypeName:
            respInfo = "Fail to find current proxy type name in config proxy page"
            return isUpdateOk, respInfo


        parentTableSoup = parentCellSoup.parent


        newTypeName = newProxyInfo["type"]
        newProxyValue = newProxyInfo["value"]


        curProxyValue = None
        isSameType = False
        isNeedSwitchType = True
        isNeedUpdateValue = True
        isNeedStore = True


        if newTypeName == curTypeName:
            isSameType = True
            isNeedSwitchType = False


        if (newTypeName == "关闭") and (curTypeName == "关闭"):
            isNeedUpdateValue = False
            isNeedStore = False
        else:
            if curTypeName == "手动":
                curProxyValue = self.getManualProxyValue(parentTableSoup)
            elif curTypeName == "自动":
                curProxyValue = self.getAutoProxyValue(parentTableSoup)


            if not curProxyValue:
                respInfo = "Fail to get %s proxy value" % curTypeName
                return isUpdateOk, respInfo


            if isSameType:
                isNeedSwitchType = False
                # need check value is same or not
                if newProxyValue == curProxyValue:
                    # if same, do nothing
                    isNeedUpdateValue = False
                    logging.info("No need change for same %s proxy config value %s", curTypeName, manualProxyValue)
            else:
                isNeedSwitchType = True


        # common logic process


        if isNeedSwitchType:
            # switch to new type
            isSwitchOk = self.switchToProxyType(parentTableSoup, newTypeName)
            if not isSwitchOk:
                respInfo = "Fail to switch to %s proxy" % curTypeName
                return isUpdateOk, respInfo
            isNeedStore = True


        if isNeedUpdateValue:
            if newTypeName == "手动":
                isUpateValueOk = self.setManualProxyValue(parentTableSoup, newProxyValue)
            elif newTypeName == "自动":
                isUpateValueOk = self.setAutoProxyValue(parentTableSoup, newProxyValue)


            if not isUpateValueOk:
                respInfo = "Fail to update new %s proxy config value %s" % (curTypeName, newProxyValue)
                return isUpdateOk, respInfo


            isNeedStore = True


        if isNeedStore:
            # type and/or value changed, need store
            isStoredOk = self.storeChangedProxyType()
            if not isStoredOk:
                respInfo = "Fail to store after proxy from %s switch to %s" % (curTypeName, newTypeName)
                return isUpdateOk, respInfo


        isUpdateOk = True
        oldProxyInfo = {
            "type": curTypeName,
            "value": curProxyValue,
        }
        return isUpdateOk, oldProxyInfo
以及相关相关函数:
    def getManualProxyValue(self, parentTableSoup):
        """in 配置代理 page, from parent table soup, find 手动 proxy value: server, port, authenticate


        Args:
            parentTableSoup (soup): parent table soup
        Returns:
            dict
        Raises:
        """
        manualProxyValue = None
        
        # proxyServer = None
        # proxyPort = None
        # proxyAuthenticate = None
        # <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
        proxyServerSoup = parentTableSoup.find(
            'XCUIElementTypeTextField',
            attrs={"type": "XCUIElementTypeTextField", "name": "服务器", "enabled":"true", "visible":"true"},
        )
        if not proxyServerSoup:
            return manualProxyValue
        proxyServer = proxyServerSoup.attrs.get("value", None) # '192.168.31.46'


        # <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="8081" name="端口" label="端口" enabled="true" visible="true" x="74" y="326" width="312" height="22"/>
        proxyPortSoup = parentTableSoup.find(
            'XCUIElementTypeTextField',
            attrs={"type": "XCUIElementTypeTextField", "name": "端口", "enabled":"true", "visible":"true"},
        )
        if not proxyPortSoup:
            return manualProxyValue
        proxyPort = proxyPortSoup.attrs.get("value", None) # '8081'


        # <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="0" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
        proxyAuthenticateSoup = parentTableSoup.find(
            'XCUIElementTypeSwitch',
            attrs={"type": "XCUIElementTypeSwitch", "name": "鉴定", "enabled":"true", "visible":"true"},
        )
        if not proxyAuthenticateSoup:
            return manualProxyValue
        proxyAuthenticate = proxyAuthenticateSoup.attrs.get("value", None) # '0'


        manualProxyValue = {
            "server": proxyServer,
            "port": proxyPort,
            "authenticate": proxyAuthenticate,
        }
        logging.info("manualProxyValue=%s", manualProxyValue)
        # manualProxyValue={'server': '192.168.31.46', 'port': '8081', 'authenticate': '0'}
        return manualProxyValue


    def setManualProxyValue(self, parentTableSoup, newManualProxyValue):
        """in 配置代理 page, after changed 手动
            set new manual proxy value
                by click each item then set value


        Args:
            parentTableSoup (soup): parent table soup
            newManualProxyValue (dict): new manual proxy value dict
        Returns:
            bool
        Raises:
        """
        isUpateManualOk = False
        parentCellClassChain = "/XCUIElementTypeCell[`rect.x = 0 AND rect.width = %d`]" % self.X

        newServerValue = newManualProxyValue["server"]
        serverFieldQuery = {"type":"XCUIElementTypeTextField", "name": "服务器", "enabled": "true"}
        serverFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
        # isFoundServer, respInfo = self.findElement(query=serverFieldQuery, timeout=0.1)
        # if not isFoundServer:
        #     return False
        isInputServerOk = self.wait_element_setText_iOS(serverFieldQuery, newServerValue)
        if not isInputServerOk:
            return False
        
        newPortValue = newManualProxyValue["port"]
        portFieldQuery = {"type":"XCUIElementTypeTextField", "name": "端口", "enabled": "true"}
        portFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
        isInputPortOk = self.wait_element_setText_iOS(portFieldQuery, newPortValue)
        if not isInputPortOk:
            return False

        newAuthenticateValue = newManualProxyValue["authenticate"]
        authSwitchQuery = {"type":"XCUIElementTypeSwitch", "name": "鉴定", "enabled": "true"}
        authSwitchQuery["parent_class_chains"] = [ parentCellClassChain ]
        foundAuth, respInfo = self.findElement(authSwitchQuery, timeout=0.1)
        if not foundAuth:
            return False


        authSwitchElement = respInfo
        curAuthValue = authSwitchElement.value
        curAuthValueStr = str(curAuthValue)
        if curAuthValueStr != newAuthenticateValue:
            # click switch element to change value
            isClickOk = self.clickElement(authSwitchElement)
            if not isClickOk:
                return False


        isUpateManualOk = True
        return isUpateManualOk


    def getAutoProxyValue(self, parentTableSoup):
        """in 配置代理 page, from parent table soup, find 自动 proxy value: url


        Args:
            parentTableSoup (soup): parent table soup
        Returns:
            dict
        Raises:
        """
        autoProxyValue = None
        
        autoUrlSoup = parentTableSoup.find(
            'XCUIElementTypeTextField',
            attrs={"type": "XCUIElementTypeTextField", "name": "URL", "enabled":"true", "visible":"true"},
        )
        if not autoUrlSoup:
            return autoProxyValue
        autoProxyValue = autoUrlSoup.attrs.get("value", None) # 'your_auto_proxy_url'
        return autoProxyValue


    def switchToProxyType(self, parentTableSoup, newProxyTypeName):
        """in 配置代理 page, switch to new proxy type


        Args:
            parentTableSoup (soup): parent table soup
            newProxyTypeName (str): new proxy type name
        Returns:
            bool
        Raises:
        """
        isSwitchOk = False

        newProxySoup = parentTableSoup.find(
            'XCUIElementTypeStaticText',
            attrs={"type": "XCUIElementTypeStaticText", "value": newProxyTypeName, "enabled":"true", "visible":"true"},
        )
        if newProxySoup:
            clickedNewProxy = self.clickElementCenterPosition(newProxySoup)
            if clickedNewProxy:
                isSwitchOk = True
        return isSwitchOk


    def storeChangedProxyType(self):
        """in 配置代理 page, save changed proxy type, by click navigation bar 存储 button


        Args:
            parentTableSoup (soup): parent table soup
            newProxyTypeName (str): new proxy type name
        Returns:
            bool
        Raises:
        """
        isStoredOk = False
        storeName = "存储"
        parentNaviBarClassChain = "/XCUIElementTypeNavigationBar[`name = '配置代理' AND rect.x = 0 AND rect.width = %d`]" % self.X
        storeButtonQuery = {"type":"XCUIElementTypeButton", "name": storeName, "enabled": "true"}
        storeButtonQuery["parent_class_chains"] = [ parentNaviBarClassChain ]
        foundAndClickedStore = self.findAndClickElement(query=storeButtonQuery, timeout=0.1)
        isStoredOk = foundAndClickedStore
        return isStoredOk
和调用:
        """iOS launch Settings, into WiFi list page, find current WiFi, into WiFi detail page
            then try update to new proxy config info

        Args:
            newProxyInfo (dict): new proxy config info
        Returns:
            bool, dict/str
                True, old proxy config info dict
                False, error message str
        Raises:
        """
        isUpdateProxyOk = False
        respInfo = None

        isGetProxyTypeOk, respInfo = self.iOSLaunchSettingsAndGetProxyType()
        if not isGetProxyTypeOk:
            respInfo = "Not find current WiFi proxy config type"
            return isUpdateProxyOk, respInfo

        curProxySoup = respInfo
        curProxyAttrDict = curProxySoup.attrs
        curTypeName = curProxyAttrDict.get("value")

        newTypeName = newProxyInfo["type"]
        if (newTypeName == "关闭") and (curTypeName == "关闭"):
            isUpdateProxyOk = True
            oldProxyInfo = {
                "type": "关闭",
                "value": None,
            }
            respInfo = oldProxyInfo
            return isUpdateProxyOk, respInfo
        else:
            # into config proxy page
            self.clickElementCenterPosition(curProxySoup)
            # get old proxy value
            # update to close
            # save
            isUpdateProxyOk, respInfo = self.iOSProxyConfigUpdateProxy(newProxyInfo)
            return isUpdateProxyOk, respInfo
去调试
分别测试:
  • 手动 -》 关闭
  • 关闭 -》 手动
发现 新的是 关闭,则无需更新值
所以:
        # if (newTypeName == "关闭") and (curTypeName == "关闭"):
        if newTypeName == "关闭":
继续,发现,两个都是 关闭,则无需 保存:
        if newTypeName == "关闭":
            isNeedUpdateValue = False

            if curTypeName == "关闭":
                isNeedStore = False
继续:
又新增一个 是否要获取当前的值
        isNeedUpdateNewValue = True

        if newTypeName == curTypeName:
            isSameType = True
            isNeedSwitchType = False

        # if (newTypeName == "关闭") and (curTypeName == "关闭"):
        if newTypeName == "关闭":
            isNeedUpdateNewValue = False

            if curTypeName == "关闭":
                isNeedStore = False
                isNeedGetCurValue = False

        if isNeedGetCurValue:
            if curTypeName == "手动":
                curProxyValue = self.getManualProxyValue(parentTableSoup)
            elif curTypeName == "自动":
                curProxyValue = self.getAutoProxyValue(parentTableSoup)

            if not curProxyValue:
                respInfo = "Fail to get %s proxy value" % curTypeName
                return isUpdateOk, respInfo

        if isSameType:
            isNeedSwitchType = False
            # need check value is same or not
            if newProxyValue == curProxyValue:
                # if same, do nothing
                isNeedUpdateNewValue = False
                logging.info("No need change for same %s proxy config value %s", curTypeName, manualProxyValue)
        else:
            isNeedSwitchType = True
调试
额外又加上isNeedCompareValue
以及结构优化:
        if isNeedSwitchType:
            # switch to new type
            isSwitchOk = self.switchToProxyType(parentTableSoup, newTypeName)
            if isSwitchOk:
                isNeedStore = True
            else:
                respInfo = "Fail to switch to %s proxy" % curTypeName
                return isUpdateOk, respInfo

        if isNeedUpdateNewValue:
            if newTypeName == "手动":
                isUpateValueOk = self.setManualProxyValue(parentTableSoup, newProxyValue)
            elif newTypeName == "自动":
                isUpateValueOk = self.setAutoProxyValue(parentTableSoup, newProxyValue)

            if isUpateValueOk:
                isNeedStore = True
            else:
                respInfo = "Fail to update new %s proxy config value %s" % (curTypeName, newProxyValue)
                return isUpdateOk, respInfo
还缺了个setAutoProxyValue
    def setAutoProxyValue(self, parentTableSoup, newAutoProxyValue):
        """in 配置代理 page, after changed to 自动
            set new manual proxy value
                by click each item then set value

        Args:
            parentTableSoup (soup): parent table soup
            newAutoProxyValue (dict): new auto proxy value dict
        Returns:
            bool
        Raises:
        """
        isUpdateAutoOk = False
        
        newUrlValue = newAutoProxyValue["url"]
        parentCellClassChain = "/XCUIElementTypeCell[`rect.x = 0 AND rect.width = %d`]" % self.X
        urlFieldQuery = {"type":"XCUIElementTypeTextField", "name": "URL", "enabled": "true"}
        urlFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
        # foundUrl, respInfo = self.findElement(urlFieldQuery, timeout=0.1)
        # if not foundUrl:
        #     return False
        isInputUrlOk = self.wait_element_setText_iOS(urlFieldQuery, newUrlValue)
        isUpdateAutoOk = isInputUrlOk
        return isUpdateAutoOk
继续:
此处 从 手动 -》 关闭 是OK的
oldProxyInfo = {'type': '手动', 'value': {'authenticate': '0', 'port': '8081', 'server': '192.168.31.46'}}
后续log
[200612 18:17:47][DevicesMethods.py 2138] Successfull to temp disable WiFi proxy {'type': '手动', 'value': {'server': '192.168.31.46', 'port': '8081', 'authenticate': '0'}}
再去测试,从 关闭 恢复 手动:
            # restore proxy if necessary
            if proxyConfigInfo:
                # isRestoreOk = self.settingsRestoreWiFiProxy(proxyConfigInfo)
                isRestoreOk, respInfo = self.iOSWifiDetailUpdateProxy(proxyConfigInfo)
                logging.info("%s to restore previous proxy %s", isRestoreOk, proxyConfigInfo)
继续:
        if curTypeName == "关闭":
            isNeedGetCurValue = False

        if newTypeName == "关闭":
            isNeedUpdateNewValue = False

        if (newTypeName == "关闭") and (curTypeName == "关闭"):
            isNeedStore = False
            isNeedCompareValue = False
再去:
加上debug信息:
            # for debug
            proxyConfigInfo = {
                    'type': '手动',
                    'value': {
                        'server': '192.168.31.46',
                        'port': '8081',
                        'authenticate': '0'
                    }
                }
重新调试:
此处代码,是可以设置 输入 代理 服务器 的文字的
'192.168.31.46'
对应页面是:
已点击输入框,触发弹出输入法,并且输入了 192.168.31.46
不过,此次 右上角 存储 并没有触发变化 变为 蓝色,后续就无法点击。
继续调试
同样,也可以输入端口:
[200612 18:37:39][DevicesMethods.py 1578] has input text: 192.168.31.46
[200612 18:38:05][DevicesMethods.py 1578] has input text: 8081
看来担心的 端口是 数字 num pad,此处输入字符串是否OK呢
看来是可以的,没问题
继续:
此次 鉴定 获取到当前值是0 
和输入 0 一致,无需点击
再去:
【已解决】iOS自动化处理WiFi代理:支持保存和恢复开启鉴定和用户名和密码
再去测试:
类型一样 都是 手动
但是 代理值不同
原先:
            proxyConfigInfo = {
                'type': '手动',
                'value': {
                    'server': '192.168.31.46',
                    'port': '8081',
                    'authenticate': '1',
                    'authUser': 'user',
                    'authPassword': 'pwd',
                }
            }
新的:
            newProxyInfo = {
                "type": "手动",
                'value': {
                    'server': '192.168.31.47',
                    'port': '8081',
                    'authenticate': '0'
                }
            }
结果:
更新值是,出错了:
之前是:192.168.31.46
更新值是:192.168.31.47
更新后是:192.168.31.46192.168.31.47
没有替换
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                      <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                      <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46192.168.31.47" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
                      <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                      <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="313" width="394" height="2"/>
                    </XCUIElementTypeCell>
所以要去优化代码
新写入值之前,要去清除值
openatx/facebook-wda: Facebook WebDriverAgent Python Client Library (not official)
e.clear_text()
去试试,遇到了:
【已解决】facebook-wda中元素clear清除文本值无效
然后接着又遇到了其他问题:
【已解决】facebook-wda获取鉴定的value值是错误的
继续调试,终于支持了完整的功能了:
【总结】
代码:
    def iOSWifiDetailUpdateProxy(self, newProxyInfo):
        """iOS launch Settings, into WiFi list page, find current WiFi, into WiFi detail page
            then try update to new proxy config info
        Args:
            newProxyInfo (dict): new proxy config info
        Returns:
            bool, dict/str
                True, old proxy config info dict
                False, error message str
        Raises:
        """
        isUpdateProxyOk = False
        respInfo = None


        isGetProxyTypeOk, respInfo = self.iOSLaunchSettingsAndGetProxyType()
        if not isGetProxyTypeOk:
            respInfo = "Not find current WiFi proxy config type"
            return isUpdateProxyOk, respInfo


        curProxySoup = respInfo
        curProxyAttrDict = curProxySoup.attrs
        curTypeName = curProxyAttrDict.get("value")


        newTypeName = newProxyInfo["type"]
        if (newTypeName == "关闭") and (curTypeName == "关闭"):
            isUpdateProxyOk = True
            oldProxyInfo = {
                "type": "关闭",
                "value": None,
            }
            respInfo = oldProxyInfo
            return isUpdateProxyOk, respInfo
        else:
            # into config proxy page
            self.clickElementCenterPosition(curProxySoup)
            # get old proxy value
            # update to close
            # save
            isUpdateProxyOk, respInfo = self.iOSProxyConfigUpdateProxy(newProxyInfo)
            logging.info("Update proxy result: %s, %s", isUpdateProxyOk, respInfo)
            return isUpdateProxyOk, respInfo
内部核心实现是:
    # def iOSRestoreWiFiProxy(self, previousProxyInfo):
    # def iOSDisableWiFiProxy(self):
    def iOSProxyConfigUpdateProxy(self, newProxyInfo):
        """in proxy config = 代理配置 page, update proxy type


        Args:
            newProxyInfo (dict): new proxy info
        Returns:
            bool, dict/str
                True, old proxy config info
                False, error message str
        Raises:
        Examples:
            newProxyInfo exmaples:
                (1) to close:
                    {
                        "type": "关闭",
                        "value": None
                    }
                (2) to manual, no auth:
                    {
                        'type': '手动',
                        'value': {
                            'server': '192.168.31.47',
                            'port': '8081',
                            'authenticate': '0',
                            'authUser': None,
                            'authPassword': None
                        }
                    }
                (3) to manual, with auth:
                    {
                        'type': '手动',
                        'value': {
                            'server': '192.168.31.47',
                            'port': '8081',
                            'authenticate': '1'
                            'authUser': 'user',
                            'authPassword': 'password'
                        }
                    }
                (4) to auto:
                    {
                        'type': '自动',
                        'value': {
                            'url': 'your_auto_proxy_url'
                        }
                    }
        """
        isUpdateOk = False
        respInfo = None
        """
            设置 无线局域网 配置代理 关闭:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="99" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="350" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                        <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="116" width="14" height="11"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="374" height="45"/>
                    </XCUIElementTypeCell>
                </XCUIElementTypeTable>


            设置 无线局域网 配置代理 手动:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="99" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="350" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                        <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="161" width="14" height="11"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="374" height="45"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="313" width="394" height="2"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="314" width="414" height="46">
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="8081" name="端口" label="端口" enabled="true" visible="true" x="74" y="326" width="312" height="22"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="358" width="305" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="359" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" value="0" enabled="true" visible="true" x="0" y="359" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="404" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="鉴定" name="鉴定" label="鉴定" enabled="true" visible="true" x="20" y="359" width="323" height="46"/>
                        <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="0" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
                    </XCUIElementTypeCell>
                </XCUIElementTypeTable>


            设置 无线局域网 配置代理 自动:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="99" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="350" height="45"/>
                        <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="206" width="14" height="11"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" name="URL" label="URL" enabled="true" visible="true" x="72" y="281" width="314" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="313" width="414" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                    </XCUIElementTypeCell>
                </XCUIElementTypeTable>
        """
        # check current proxy type: 手动/自动/关闭
        curPageXml = self.get_page_source()
        soup = CommonUtils.xmlToSoup(curPageXml)
        morenInfoChainList = [
            {
                "tag": "XCUIElementTypeTable",
                "attrs": self.FullScreenAttrDict
            },
            {
                "tag": "XCUIElementTypeCell",
                "attrs": {"enabled":"true", "visible":"true", "x":"0", "width":"%s" % self.X}
            },
            {
                "tag": "XCUIElementTypeButton",
                # "attrs": {"enabled":"false", "visible":"true", "name": "更多信息"}
                "attrs": {"visible":"true", "name": "更多信息"}
            },
        ]
        morenInfoSoup = CommonUtils.bsChainFind(soup, morenInfoChainList)
        if not morenInfoSoup:
            respInfo = "Fail to find 更多信息 in config proxy page"
            return isUpdateOk, respInfo


        parentCellSoup = morenInfoSoup.parent
        curTypeName = self.iOSFindChildProxyType(parentCellSoup)
        if not curTypeName:
            respInfo = "Fail to find current proxy type name in config proxy page"
            return isUpdateOk, respInfo


        parentTableSoup = parentCellSoup.parent


        newTypeName = newProxyInfo["type"]
        newProxyValue = newProxyInfo["value"]


        curProxyValue = None
        isSameType = False
        isNeedSwitchType = True
        isNeedGetCurValue = True
        isNeedCompareValue = False
        isNeedUpdateNewValue = True
        isNeedStore = True


        if newTypeName == curTypeName:
            isSameType = True
            isNeedSwitchType = False
            isNeedCompareValue = True
        else:
            isNeedSwitchType = True


        if curTypeName == "关闭":
            isNeedGetCurValue = False


        if newTypeName == "关闭":
            isNeedUpdateNewValue = False


        if (newTypeName == "关闭") and (curTypeName == "关闭"):
            isNeedStore = False
            isNeedCompareValue = False


        if isNeedGetCurValue:
            if curTypeName == "手动":
                curProxyValue = self.getManualProxyValue(parentTableSoup)
            elif curTypeName == "自动":
                curProxyValue = self.getAutoProxyValue(parentTableSoup)


            if not curProxyValue:
                respInfo = "Fail to get %s proxy value" % curTypeName
                return isUpdateOk, respInfo


        if isNeedCompareValue:
            # need check value is same or not
            if newProxyValue == curProxyValue:
                # if same, do nothing
                isNeedUpdateNewValue = False
                logging.info("No need change for same proxy type %s and value %s", curTypeName, curProxyValue)


        # common logic process


        if isNeedSwitchType:
            # switch to new type
            isSwitchOk = self.switchToProxyType(parentTableSoup, newTypeName)
            if isSwitchOk:
                isNeedStore = True
            else:
                respInfo = "Fail to switch to %s proxy" % curTypeName
                return isUpdateOk, respInfo


        if isNeedUpdateNewValue:
            if newTypeName == "手动":
                isUpateValueOk = self.setManualProxyValue(parentTableSoup, newProxyValue)
            elif newTypeName == "自动":
                isUpateValueOk = self.setAutoProxyValue(parentTableSoup, newProxyValue)


            if isUpateValueOk:
                isNeedStore = True
            else:
                respInfo = "Fail to update new %s proxy config value %s" % (curTypeName, newProxyValue)
                return isUpdateOk, respInfo


        if isNeedStore:
            # type and/or value changed, need store
            isStoredOk = self.storeChangedProxyType()
            if not isStoredOk:
                respInfo = "Fail to store after proxy from %s switch to %s" % (curTypeName, newTypeName)
                return isUpdateOk, respInfo


        isUpdateOk = True
        oldProxyInfo = {
            "type": curTypeName,
            "value": curProxyValue,
        }
        return isUpdateOk, oldProxyInfo
其中就是上述这个函数,耗时最长,因为多种逻辑都要考虑:
理论上有 3种输入(关闭、手动、自动),3种当前值(关闭、手动、自动)
以及对于手动,还有 是否开启 鉴定auth,以及 对于同样类型,还涉及到update更新现有的值
所以加起来有10多种情况,经过大量的调试和优化,才有上面,看起来,貌似代码不多,但是逻辑足够强大到支持上面说的10多种情况。
以及其他被调用的函数:
    def iOSFindChildProxyType(self, parentCellSoup, isReturnSoup=False):
        """from parent cell soup, find child proxy type node / node's name


        Args:
            parentCellSoup (soup): Beautifulsoup soup of parent XCUIElementTypeCell
            isReturnSoup (bool): return soup if true, otherwise return soup's name
        Returns:
            str/soup:
                str: 手动/自动/关闭
                soup: soup node
        Raises:
        """
        # proxyTypeName = None
        # some cases:
        """
            设置 无线局域网 详情页 代理 关闭:
                <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="695" width="414" height="46">
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="695" width="414" height="1"/>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="740" width="414" height="1"/>
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="配置代理" name="配置代理" label="配置代理" enabled="true" visible="true" x="20" y="708" width="70" height="21"/>
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="341" y="708" width="35" height="21"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="386" y="711" width="8" height="14"/>
                </XCUIElementTypeCell>


            设置 无线局域网 详情页 代理 手动:
                <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="695" width="414" height="46">
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="695" width="414" height="1"/>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="740" width="414" height="1"/>
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="配置代理" name="配置代理" label="配置代理" enabled="true" visible="true" x="20" y="708" width="70" height="21"/>
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="341" y="708" width="35" height="21"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="386" y="711" width="8" height="14"/>
                </XCUIElementTypeCell>


            设置 无线局域网 配置代理 手动:
                <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="350" height="45"/>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="161" width="14" height="11"/>
                </XCUIElementTypeCell>


            设置 无线局域网 配置代理 关闭:
                <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="99" width="414" height="1"/>
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="350" height="45"/>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="116" width="14" height="11"/>
                </XCUIElementTypeCell>


            设置 无线局域网 配置代理 自动:
                <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                    <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="350" height="45"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="206" width="14" height="11"/>
                </XCUIElementTypeCell>
        """
        proxyTypeP = re.compile("(手动)|(自动)|(关闭)")
        proxyTypeSoup = parentCellSoup.find(
            'XCUIElementTypeStaticText',
            attrs={"type": "XCUIElementTypeStaticText", "value": proxyTypeP, "enabled":"true", "visible":"true"},
        )
        if isReturnSoup:
            return proxyTypeSoup
        else:
            proxySoupAttrDict = proxyTypeSoup.attrs
            proxyTypeName = proxySoupAttrDict.get("value")
            return proxyTypeName # '手动’
获取 当前手动类型时的 值:
    def getManualProxyValue(self, parentTableSoup):
        """in 配置代理 page, from parent table soup, find 手动 proxy value: server, port, authenticate


        Args:
            parentTableSoup (soup): parent table soup
        Returns:
            dict
        Raises:
        """
        manualProxyValue = None
        """
            设置 无线局域网 配置代理 手动:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="99" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="350" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                        <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="161" width="14" height="11"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="374" height="45"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="313" width="394" height="2"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="314" width="414" height="46">
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="8081" name="端口" label="端口" enabled="true" visible="true" x="74" y="326" width="312" height="22"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="358" width="305" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="359" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" value="0" enabled="true" visible="true" x="0" y="359" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="404" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="鉴定" name="鉴定" label="鉴定" enabled="true" visible="true" x="20" y="359" width="323" height="46"/>
                        <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="0" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
                    </XCUIElementTypeCell>
                </XCUIElementTypeTable>


            设置 无线局域网 配置代理 手动 开启 鉴定:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="99" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="350" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                        <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="161" width="14" height="11"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="374" height="45"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="313" width="394" height="2"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="314" width="414" height="46">
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="8081" name="端口" label="端口" enabled="true" visible="true" x="74" y="326" width="312" height="22"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="358" width="305" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="359" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" value="1" enabled="true" visible="true" x="0" y="359" width="414" height="46">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="鉴定" name="鉴定" label="鉴定" enabled="true" visible="true" x="20" y="359" width="323" height="46"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="404" width="394" height="1"/>
                        <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="1" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="404" width="414" height="46">
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="user" name="用户名" label="用户名" enabled="true" visible="true" x="92" y="416" width="294" height="22"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="448" width="305" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="449" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="449" width="414" height="47">
                        <XCUIElementTypeSecureTextField type="XCUIElementTypeSecureTextField" value="•••" name="密码" label="密码" enabled="true" visible="true" x="74" y="461" width="312" height="22"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="494" width="414" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="493" width="305" height="2"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="495" width="414" height="31">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="您的凭证可能以不加密方式发送" name="您的凭证可能以不加密方式发送" label="您的凭证可能以不加密方式发送" enabled="true" visible="true" x="0" y="495" width="414" height="31"/>
                    </XCUIElementTypeOther>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" name="您的凭证可能以不加密方式发送" label="您的凭证可能以不加密方式发送" enabled="true" visible="false" x="0" y="495" width="414" height="31"/>
                </XCUIElementTypeTable>
        """
        # proxyServer = None
        # proxyPort = None
        # proxyAuthenticate = None
        # <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
        proxyServerSoup = parentTableSoup.find(
            'XCUIElementTypeTextField',
            attrs={"type": "XCUIElementTypeTextField", "name": "服务器", "enabled":"true", "visible":"true"},
        )
        if not proxyServerSoup:
            return manualProxyValue
        proxyServer = proxyServerSoup.attrs.get("value", None) # '192.168.31.46'


        # <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="8081" name="端口" label="端口" enabled="true" visible="true" x="74" y="326" width="312" height="22"/>
        proxyPortSoup = parentTableSoup.find(
            'XCUIElementTypeTextField',
            attrs={"type": "XCUIElementTypeTextField", "name": "端口", "enabled":"true", "visible":"true"},
        )
        if not proxyPortSoup:
            return manualProxyValue
        proxyPort = proxyPortSoup.attrs.get("value", None) # '8081'


        # <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="0" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
        proxyAuthenticateSoup = parentTableSoup.find(
            'XCUIElementTypeSwitch',
            attrs={"type": "XCUIElementTypeSwitch", "name": "鉴定", "enabled":"true", "visible":"true"},
        )
        if not proxyAuthenticateSoup:
            return manualProxyValue
        proxyAuthenticate = proxyAuthenticateSoup.attrs.get("value", None) # '0'


        authUser = None
        authPassword = None


        if proxyAuthenticate == "1":
            # need save user and password
            # <XCUIElementTypeTextField type="XCUIElementTypeTextField" name="用户名" label="用户名" enabled="true" visible="true" x="92" y="416" width="294" height="22"/>
            authUserSoup = parentTableSoup.find(
                'XCUIElementTypeTextField',
                attrs={"type": "XCUIElementTypeTextField", "name": "用户名", "enabled":"true", "visible":"true"},
            )
            if not authUserSoup:
                return manualProxyValue
            authUser = authUserSoup.attrs.get("value", None) # 'user'


            # <XCUIElementTypeSecureTextField type="XCUIElementTypeSecureTextField" name="密码" label="密码" enabled="true" visible="true" x="74" y="461" width="312" height="22"/>
            authPasswordSoup = parentTableSoup.find(
                'XCUIElementTypeSecureTextField',
                attrs={"type": "XCUIElementTypeSecureTextField", "name": "密码", "enabled":"true", "visible":"true"},
            )
            if not authPasswordSoup:
                return manualProxyValue
            authPassword = authPasswordSoup.attrs.get("value", None) # '•••'
            if '•' in authPassword:
                logging.warning("Get proxy autheticate password only get dot • -> Please user self makesure the password is correct !")


        manualProxyValue = {
            "server": proxyServer,
            "port": proxyPort,
            "authenticate": proxyAuthenticate,
            "authUser": authUser,
            "authPassword": authPassword,
        }
        logging.info("manualProxyValue=%s", manualProxyValue)
        # manualProxyValue={'server': '192.168.31.46', 'port': '8081', 'authenticate': '0'}
        # manualProxyValue={'server': '192.168.31.46', 'port': '8081', 'authenticate': '1', 'authUser': 'user', 'authPassword': '•••'}
        return manualProxyValue
获取 当前 自动时的值:
    def getAutoProxyValue(self, parentTableSoup):
        """in 配置代理 page, from parent table soup, find 自动 proxy value: url


        Args:
            parentTableSoup (soup): parent table soup
        Returns:
            dict
        Raises:
        """
        autoProxyValue = None
        """
            设置 无线局域网 配置代理 自动:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="false" x="0" y="99" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="143" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="144" width="414" height="45">
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="374" height="45"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="188" width="394" height="1"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="189" width="414" height="45">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="233" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="350" height="45"/>
                        <XCUIElementTypeButton type="XCUIElementTypeButton" name="更多信息" label="更多信息" enabled="false" visible="true" x="380" y="206" width="14" height="11"/>
                    </XCUIElementTypeCell>
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="your_auto_proxy_url" name="URL" label="URL" enabled="true" visible="true" x="72" y="281" width="314" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="313" width="414" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                    </XCUIElementTypeCell>
                </XCUIElementTypeTable>
        """
        autoUrlSoup = parentTableSoup.find(
            'XCUIElementTypeTextField',
            attrs={"type": "XCUIElementTypeTextField", "name": "URL", "enabled":"true", "visible":"true"},
        )
        if not autoUrlSoup:
            return autoProxyValue
        autoProxyValue = autoUrlSoup.attrs.get("value", None) # 'your_auto_proxy_url'
        return autoProxyValue
切换类型:
    def switchToProxyType(self, parentTableSoup, newProxyTypeName):
        """in 配置代理 page, switch to new proxy type


        Args:
            parentTableSoup (soup): parent table soup
            newProxyTypeName (str): new proxy type name
        Returns:
            bool
        Raises:
        """
        isSwitchOk = False
        """
            设置 无线局域网 配置代理 手动:
                <XCUIElementTypeTable type="XCUIElementTypeTable" enabled="true" visible="true" x="0" y="0" width="414" height="736">
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="99" width="414" height="45">
                        ...
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="关闭" name="关闭" label="关闭" enabled="true" visible="true" x="20" y="99" width="374" height="45"/>


                        。。。
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="手动" name="手动" label="手动" enabled="true" visible="true" x="20" y="144" width="350" height="45"/>


                        。。。
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="自动" name="自动" label="自动" enabled="true" visible="true" x="20" y="189" width="374" height="45"/>
        """
        newProxySoup = parentTableSoup.find(
            'XCUIElementTypeStaticText',
            attrs={"type": "XCUIElementTypeStaticText", "value": newProxyTypeName, "enabled":"true", "visible":"true"},
        )
        if newProxySoup:
            clickedNewProxy = self.clickElementCenterPosition(newProxySoup)
            if clickedNewProxy:
                isSwitchOk = True
        return isSwitchOk
设置 手动 的值:
    def setManualProxyValue(self, parentTableSoup, newManualProxyValue):
        """in 配置代理 page, after changed to 手动
            set new manual proxy value


        Args:
            parentTableSoup (soup): parent table soup
            newManualProxyValue (dict): new manual proxy value dict
        Returns:
            bool
        Raises:
        """
        isUpateManualOk = False
        """
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="192.168.31.46" name="服务器" label="服务器" enabled="true" visible="true" x="92" y="281" width="294" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="313" width="394" height="2"/>
                    </XCUIElementTypeCell>
        """
        parentCellClassChain = "/XCUIElementTypeCell[`rect.x = 0 AND rect.width = %d`]" % self.X


        newServerValue = newManualProxyValue["server"]
        serverFieldQuery = {"type":"XCUIElementTypeTextField", "name": "服务器", "enabled": "true"}
        serverFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
        # isFoundServer, respInfo = self.findElement(query=serverFieldQuery, timeout=0.1)
        # if not isFoundServer:
        #     return False
        isInputServerOk = self.wait_element_setText_iOS(serverFieldQuery, newServerValue)
        if not isInputServerOk:
            return False
        
        """
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="314" width="414" height="46">
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="8081" name="端口" label="端口" enabled="true" visible="true" x="74" y="326" width="312" height="22"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="358" width="305" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="20" y="359" width="394" height="1"/>
                    </XCUIElementTypeCell>
        """
        newPortValue = newManualProxyValue["port"]
        portFieldQuery = {"type":"XCUIElementTypeTextField", "name": "端口", "enabled": "true"}
        portFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
        isInputPortOk = self.wait_element_setText_iOS(portFieldQuery, newPortValue)
        if not isInputPortOk:
            return False


        """
                    <XCUIElementTypeCell type="XCUIElementTypeCell" value="0" enabled="true" visible="true" x="0" y="359" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="404" width="414" height="1"/>
                        <XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value="鉴定" name="鉴定" label="鉴定" enabled="true" visible="true" x="20" y="359" width="323" height="46"/>
                        <XCUIElementTypeSwitch type="XCUIElementTypeSwitch" value="0" name="鉴定" label="鉴定" enabled="true" visible="true" x="343" y="366" width="51" height="32"/>
                    </XCUIElementTypeCell>
        """
        newAuthenticateValue = newManualProxyValue["authenticate"]
        authSwitchQuery = {"type":"XCUIElementTypeSwitch", "name": "鉴定", "enabled": "true"}
        authSwitchQuery["parent_class_chains"] = [ parentCellClassChain ]
        foundAuth, respInfo = self.findElement(authSwitchQuery, timeout=0.1)
        if not foundAuth:
            return False


        authSwitchElement = respInfo


        curAuthValueStr = ""
        # curAuthValue = authSwitchElement.value # '0'
        # curAuthValueStr = str(curAuthValue)
        # Special: sometime wda element value is WRONG, actual is '1', but got '0'
        # so change to bs find then get value from page source xml
        curPageXml = self.get_page_source()
        soup = CommonUtils.xmlToSoup(curPageXml)
        authSwitchChainList = [
            {
                "tag": "XCUIElementTypeTable",
                "attrs": self.FullScreenAttrDict
            },
            {
                "tag": "XCUIElementTypeCell",
                "attrs": {"enabled":"true", "visible":"true", "x":"0", "width":"%s" % self.X}
            },
            {
                "tag": "XCUIElementTypeSwitch",
                "attrs": {"enabled":"true", "visible":"true", "name": "鉴定"}
            },
        ]
        authSwitchSoup = CommonUtils.bsChainFind(soup, authSwitchChainList)
        if authSwitchSoup:
            curAuthValue =  authSwitchSoup.attrs.get("value", None)
            if curAuthValue:
                curAuthValueStr = str(curAuthValue)
        
        if curAuthValueStr == "":
            return False


        if curAuthValueStr != newAuthenticateValue:
            # click switch element to change value
            isClickOk = self.clickElement(authSwitchElement)
            if not isClickOk:
                return False


        if newAuthenticateValue == "1":
            # need restore auth user and password
            newAuthUserValue = newManualProxyValue["authUser"]
            userFieldQuery = {"type":"XCUIElementTypeTextField", "name": "用户名", "enabled": "true"}
            userFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
            isInputUserOk = self.wait_element_setText_iOS(userFieldQuery, newAuthUserValue)
            if not isInputUserOk:
                return False


            newAuthPasswordValue = newManualProxyValue["authPassword"]
            passwordFieldQuery = {"type":"XCUIElementTypeSecureTextField", "name": "密码", "enabled": "true"}
            passwordFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
            isInputPasswordOk = self.wait_element_setText_iOS(passwordFieldQuery, newAuthPasswordValue)
            if not isInputPasswordOk:
                return False
设置 自动 的值:
    def setAutoProxyValue(self, parentTableSoup, newAutoProxyValue):
        """in 配置代理 page, after changed to 自动
            set new manual proxy value
                by click each item then set value


        Args:
            parentTableSoup (soup): parent table soup
            newAutoProxyValue (dict): new auto proxy value dict
        Returns:
            bool
        Raises:
        """
        isUpdateAutoOk = False
        """
                    <XCUIElementTypeCell type="XCUIElementTypeCell" enabled="true" visible="true" x="0" y="269" width="414" height="46">
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="269" width="414" height="1"/>
                        <XCUIElementTypeTextField type="XCUIElementTypeTextField" value="your_auto_proxy_url" name="URL" label="URL" enabled="true" visible="true" x="72" y="281" width="314" height="21"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="0" y="313" width="414" height="2"/>
                        <XCUIElementTypeOther type="XCUIElementTypeOther" enabled="true" visible="true" x="15" y="313" width="305" height="1"/>
                    </XCUIElementTypeCell>
        """
        newUrlValue = newAutoProxyValue["url"]
        parentCellClassChain = "/XCUIElementTypeCell[`rect.x = 0 AND rect.width = %d`]" % self.X
        urlFieldQuery = {"type":"XCUIElementTypeTextField", "name": "URL", "enabled": "true"}
        urlFieldQuery["parent_class_chains"] = [ parentCellClassChain ]
        # foundUrl, respInfo = self.findElement(urlFieldQuery, timeout=0.1)
        # if not foundUrl:
        #     return False
        isInputUrlOk = self.wait_element_setText_iOS(urlFieldQuery, newUrlValue)
        isUpdateAutoOk = isInputUrlOk
        return isUpdateAutoOk
有改动后,点击 存储 去保存改动:
    def storeChangedProxyType(self):
        """in 配置代理 page, save changed proxy type, by click navigation bar 存储 button


        Args:
            parentTableSoup (soup): parent table soup
            newProxyTypeName (str): new proxy type name
        Returns:
            bool
        Raises:
        """
        isStoredOk = False
        """
            设置 WiFi 配置代理 从手动切换到 关闭 存储:
                <XCUIElementTypeNavigationBar type="XCUIElementTypeNavigationBar" name="配置代理" enabled="true" visible="true" x="0" y="20" width="414" height="44">
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="xxx_guest_5G" label="xxx_guest_5G" enabled="true" visible="true" x="0" y="20" width="155" height="44"/>
                    <XCUIElementTypeOther type="XCUIElementTypeOther" name="配置代理" label="配置代理" enabled="true" visible="true" x="172" y="31" width="70" height="21"/>
                    <XCUIElementTypeButton type="XCUIElementTypeButton" name="存储" label="存储" enabled="true" visible="true" x="359" y="20" width="43" height="44"/>
                </XCUIElementTypeNavigationBar>
        """
        storeName = "存储"
        parentNaviBarClassChain = "/XCUIElementTypeNavigationBar[`name = '配置代理' AND rect.x = 0 AND rect.width = %d`]" % self.X
        storeButtonQuery = {"type":"XCUIElementTypeButton", "name": storeName, "enabled": "true"}
        storeButtonQuery["parent_class_chains"] = [ parentNaviBarClassChain ]
        foundAndClickedStore = self.findAndClickElement(query=storeButtonQuery, timeout=0.1)
        isStoredOk = foundAndClickedStore
        return isStoredOk
调试:
(1)之前:手动,要改为:关闭:
输入:
{
    "type": "关闭",
    "value": None
}
返回:
{
    'type': '手动',
    'value': {
        'server': '192.168.31.47',
        'port': '8081',
        'authenticate': '0',
        'authUser': None,
        'authPassword': None
    }
}
(2)之前:关闭,(恢复)改为:手动
{
    'type': '手动',
    'value': {
        'server': '192.168.31.47',
        'port': '8081',
        'authenticate': '0',
        'authUser': None,
        'authPassword': None
    }
}
返回:
{
    "type": "关闭",
    "value": None
}
需要额外说明的:
对于 鉴定=1时,即开启了auth时,虽然能获取到当前的 用户名 和 密码
但是密码是 黑点点
'•••'
无法获取真正的密码明文
-》需要用户自己,在恢复之前,设置为正确的真正的密码。

转载请注明:在路上 » 【已解决】iOS自动化处理WiFi代理:WiFi详情页中更新代理配置信息

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
90 queries in 0.207 seconds, using 23.57MB memory