Appium Appium 切换到 webview 页面,使用 ActionChains 时候,报 “Original error: 501 - "unimplemented command” 错误。麻烦帮忙看下

Forkey · 2019年06月18日 · 最后由 Forkey 回复于 2019年06月20日 · 3098 次阅读

设备信息 -- 华为手机

desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '8.1.0'
desired_caps['deviceName'] = 'XKKBB19114154873'
desired_caps['appPackage'] = 'com.ffk.uotc.debug'
desired_caps['appActivity'] = 'com.ffk.uotc.mvp.ui.activity.WelcomeActivity'
desired_caps['chromedriverExecutableDir']='E:\CompanyInformation\Workplace\APPIUM\demo'

报错的代码

# 开始移动
    def start_move(self, distance):
        element = self.driver.find_element_by_xpath('//div[@class="geetest_slider_button"]')

        # 这里就是根据移动进行调试,计算出来的位置不是百分百正确的,加上一点偏移
        print("方块的宽度:" + str(element.size.get('width')))
        # distance -= element.size.get('width') / 2
        # distance += 25
        distance += element.size.get('width') / 2
        print("最后的间距:" + str(distance))
        action = ActionChains(self.driver)
        time.sleep(0.5)
        # 初始化步调值
        span = 0
        while distance > 0:

            span += 3
            print(span)
            action.click_and_hold(element).move_by_offset(span, 0).perform()
            distance -= 3
            # time.sleep(random.randint(10, 50) / 100)
            action = ActionChains(self.driver)

        # action.move_by_offset(distance, 1).perform()
        action.release(on_element=element).perform()
        # action.release().perform()

代码错误信息如下:

Traceback (most recent call last):
  File "E:/CompanyInformation/Workplace/APPIUM/demo/Calculator.py", line 52, in <module>
    b.visit_index()
  File "E:\CompanyInformation\Workplace\APPIUM\demo\Verity.py", line 25, in visit_index
    self.analog_drag()
  File "E:\CompanyInformation\Workplace\APPIUM\demo\Verity.py", line 45, in analog_drag
    self.start_move(distance)
  File "E:\CompanyInformation\Workplace\APPIUM\demo\Verity.py", line 112, in start_move
    action.click_and_hold(element).move_by_offset(span, 0).perform()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\common\action_chains.py", line 80, in perform
    self.w3c_actions.perform()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\common\actions\action_builder.py", line 76, in perform
    self.driver.execute(Command.W3C_ACTIONS, enc)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\appium\webdriver\errorhandler.py", line 29, in check_response
    raise wde
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\appium\webdriver\errorhandler.py", line 24, in check_response
    super(MobileErrorHandler, self).check_response(response)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Could not proxy. Proxy error: Could not proxy command to remote server. Original error: 501 - "unimplemented command: session/07befb9ea2b39e205abbf5611cdb76b0/actions"
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 15 条回复 时间 点赞

@chenhengjie123 @lose 麻烦帮忙看下😁

Forkey 回复

你这是 python 脚本日志,得看看 appium 日志

你在调用这个方法之前,必然是切换了 driver 吧,driver 在切换到 webview 的 context 后,就不支持手势操作了

cmlanche 回复

appium 日志

[W3C (acb3d50f)] Driver proxy active, passing request on via HTTP proxy
[WD Proxy] Matched '/wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/element/0.6742245843108476-3/size' to command name 'getSize'
[WD Proxy] Proxying [GET /wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/element/0.6742245843108476-3/size] to [GET http://127.0.0.1:8000/wd/hub/session/8f1ab4e86d833902be2f4ba7b24d79f4/element/0.6742245843108476-3/size] with body: {}
[WD Proxy] Got response with status 200: "{\"sessionId\":\"8f1ab4e86d833902be2f4ba7b24d79f4\",\"status\":0,\"value\":{\"ceil\":{},\"clone\":{},\"floor\":{},\"height\":68,\"round\":{},\"scale\":{},\"toString\":{},\"width\":68}}"
[WD Proxy] Replacing sessionId 8f1ab4e86d833902be2f4ba7b24d79f4 with acb3d50f-5a04-4977-b524-40886cd75470
[HTTP] <-- GET /wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/element/0.6742245843108476-3/size 200 39 ms - 164
[HTTP] 
[HTTP] --> POST /wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/actions
[HTTP] {"actions":[{"type":"pointer","parameters":{"pointerType":"mouse"},"id":"mouse","actions":[{"type":"pointerMove","duration":250,"x":0,"y":0,"origin":{"element-6066-11e4-a52e-4f735466cecf":"0.6742245843108476-3"}},{"type":"pointerDown","duration":0,"button":0}]},{"type":"key","id":"key","actions":[{"type":"pause","duration":0}]}],"sessionId":"acb3d50f-5a04-4977-b524-40886cd75470"}
[W3C (acb3d50f)] Driver proxy active, passing request on via HTTP proxy
[WD Proxy] Matched '/wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/actions' to command name 'performActions'
[WD Proxy] Proxying [POST /wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/actions] to [POST http://127.0.0.1:8000/wd/hub/session/8f1ab4e86d833902be2f4ba7b24d79f4/actions] with body: {"actions":[{"type":"pointer","parameters":{"pointerType":"mouse"},"id":"mouse","actions":[{"type":"pointerMove","duration":250,"x":0,"y":0,"origin":{"ELEMENT":"0.6742245843108476-3","element-6066-11e4-a52e-4f735466cecf":"0.6742245843108476-3"}},{"type":"pointerDown","duration":0,"button":0}]},{"type":"key","id":"key","actions":[{"type":"pause","duration":0}]}],"sessionId":"acb3d50f-5a04-4977-b524-40886cd75470"}
[WD Proxy] Got an unexpected response: unimplemented command: session/8f1ab4e86d833902be2f4ba7b24d79f4/actions
[W3C (acb3d50f)] Encountered internal error running command: Error: Could not proxy. Proxy error: Could not proxy command to remote server. Original error: 501 - "unimplemented command: session/8f1ab4e86d833902be2f4ba7b24d79f4/actions"
[W3C (acb3d50f)]     at doJwpProxy (C:\Program Files\Appium\resources\app\node_modules\appium-base-driver\lib\protocol\protocol.js:547:13)
[HTTP] <-- POST /wd/hub/session/acb3d50f-5a04-4977-b524-40886cd75470/actions 500 17 ms - 859
狂沙 回复

您好,我用荣耀手机 Android9 系统执行该代码是没问题的。 我切换到 webview 后可以进行滑动操作的。 只是在华为手机就不行。

注意看:unimplemented command: session/8f1ab4e86d833902be2f4ba7b24d79f4/actions

这个请求是会包装一系列请求发送过去的,通常用来做连贯的绘制,你确保在华为手机的时候,发送过去的 actions 能形成一个连贯的闭合,否则 appium 是会解析失败的

cmlanche 回复

您好,谢谢您的回答,具体代码应该如何修改才能连贯闭合呢,不是很懂。
出问题的代码如下:

# 开始移动
    def start_move(self, distance):
        element = self.driver.find_element_by_xpath('//div[@class="geetest_slider_button"]')

        # 这里就是根据移动进行调试,计算出来的位置不是百分百正确的,加上一点偏移
        print("方块的宽度:" + str(element.size.get('width')))
        # distance -= element.size.get('width') / 2
        # distance += 25
        distance += element.size.get('width') / 2
        print("最后的间距:" + str(distance))
        action = ActionChains(self.driver)
        time.sleep(0.5)
        # 初始化步调值
        span = 0
        while distance > 0:

            span += 3
            print(span)
            action.click_and_hold(element).move_by_offset(span, 0).perform()
            distance -= 3
            # time.sleep(random.randint(10, 50) / 100)
            action = ActionChains(self.driver)

        # action.move_by_offset(distance, 1).perform()
        action.release(on_element=element).perform()
        # action.release().perform()

我具体看了下主要是这行代码出问题了。 “action.click_and_hold(element).move_by_offset(span, 0).perform()”。 能帮我看下如何修改吗?

Forkey 回复

方案一:你可以做一个简单的测试,按下,滑动,弹起,在这个华为手机上看行不行,如果行,基本就可以说跟手机没关系的。
方案二:比对两个手机的时候,这个 while 循环最后产生的 actions 数量和信息是不是一致的(推荐先验证这个)

cmlanche 回复

好的,谢谢。我试下

Forkey #10 · 2019年06月19日 Author
cmlanche 回复

您好,我看了下 appium 报错日志,截图上面上是执行失败的返回日志,下面是 200 的日志,看不出来具体问题出现在哪里?

Forkey 回复

value 值不符合规则?

你是用 espresso driver 来做测试的吗?

我看这个错误只在 espresso 中才会存在:

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.appium.espressoserver.lib.helpers.w3c.processor;

import java.util.Arrays;

import io.appium.espressoserver.lib.handlers.exceptions.InvalidArgumentException;
import io.appium.espressoserver.lib.helpers.w3c.models.ActionObject;
import io.appium.espressoserver.lib.helpers.w3c.models.InputSource.Action;
import io.appium.espressoserver.lib.helpers.w3c.models.InputSource.ActionType;
import io.appium.espressoserver.lib.helpers.w3c.models.InputSource.InputSourceType;

import static io.appium.espressoserver.lib.helpers.w3c.models.InputSource.ActionType.KEY_DOWN;
import static io.appium.espressoserver.lib.helpers.w3c.models.InputSource.ActionType.KEY_UP;
import static io.appium.espressoserver.lib.helpers.w3c.models.InputSource.ActionType.PAUSE;
import static io.appium.espressoserver.lib.helpers.w3c.processor.PauseProcessor.processPauseAction;
import static io.appium.espressoserver.lib.helpers.w3c.processor.ProcessorHelpers.throwArgException;

@SuppressWarnings("unused")
public class KeyProcessor {

    /**
     * Follows the 'process a key action' algorithm in 17.2
     * @param action Action being processed
     * @param inputSourceType Source type
     * @param id ID of input source that it's part of
     * @param index Index within the 'actions' array
     * @return Processed action object
     * @throws InvalidArgumentException If failed to process, throw this. Means that args are bad.
     */
    public static ActionObject processKeyAction(Action action, InputSourceType inputSourceType, String id, int index)
            throws InvalidArgumentException {

        // 1-3 get and validate the action type
        ActionType subType = action.getType();
        ActionType[] validKeyTypes = new ActionType[]{ KEY_UP, KEY_DOWN, PAUSE };
        if (!Arrays.asList(validKeyTypes).contains(subType)) {
            throwArgException(index, id, "has an invalid type. 'type' for 'key' actions must be one of: keyUp, keyDown or pause");
        }

        // 4 if pause return PAUSE action
        if (subType.equals(PAUSE)) {
            return processPauseAction(action, inputSourceType, id, index);
        }

        // 5-7 get the Unicode value of the keystroke (verify that it's a single character)
        String key = action.getValue();

        if (key.length() != 1) {
            throwArgException(index, id, String.format("has invalid 'value' %s. Must be a unicode point", key));
        }


        ActionObject actionObject = new ActionObject(id, inputSourceType, subType, index);
        actionObject.setValue(key);
        return actionObject;
    }
}

错误说按键 key 值不是的字符长度不是 1 就会抛出异常,检查下吧

Forkey 回复

看你这个表好像是一样的

Forkey #13 · 2019年06月19日 Author
cmlanche 回复

app 里面嵌套一个极验的滑动验证,里面是有涉及到 “appium.espressoserver.lib.helpers.w3c.processor” 这里面的 w3c,我用荣耀发现都是可以正常滑动的,但是到华为手机就不行,奇怪。

我看了下,所有的 actionchains 走的都是 w3c 的,比如下面我拿出来的这个方法. 不知道为什么,是因为我导入的包问题吗? 还是说一定是走 w3c

def reset_actions(self):
    """
        Clears actions that are already stored locally and on the remote end
    """
    if self._driver.w3c:
        self.w3c_actions.clear_actions()
    self._actions = []

导入的包如下

import time, re
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from PIL import Image
import base64
from selenium import webdriver
Forkey 回复

还有个手机 logcat 日志不知道你会不会看,看 espresso 的 server 发生了什么

cmlanche 回复

好的,我看看,谢谢

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