Когда использовать неявное и явное ожидание при переключении контекстов и поиске элементов - PullRequest
1 голос
/ 06 апреля 2019

Я пытался добавить всегда использовать неявные и явные ожидания при настройке базовых универсальных функций для моей инфраструктуры мобильной автоматизации и избегать метода Thread.sleep (time) для сохранения лучших методов проектирования.В последнее время у меня были проблемы с использованием ожиданий только при использовании переключателей контекста.Я получаю следующие ошибки: TimeoutException, StaleElement References или NoSuchElement Exceptions после переключения контекстов, даже если я знаю, что при проверке нужный элемент находится в поле зрения.

Я не совсем ищу предложения для решения этой проблемы, но я хотел бы знать, является ли это хорошим подходом с использованием ожиданий со сценариями, описанными ниже.

(Правка) Сценарий 1 (Решено) Я создал функцию для имитации, если пользователь хочет возобновить активное приложение, вызывая список запущенных приложений, а затем на основе AccessibilityId, предоставленного при вызове метода, оннайдет элемент на основе этого идентификатора и выберет его, чтобы вернуться в приложение.(Код для сценария 1 приведен ниже).

Сценарий 2: Я создал функцию, которая будет продолжать смахивать в любом направлении, вверх или вниз, пока целевой элемент, введенный пользователем в методнайден.Поскольку свайпы могут работать только в собственном контексте, я переключаю установленный контекст на собственный, чтобы свайпить, затем переключаюсь обратно на веб-просмотр или любой другой вид по умолчанию для поиска целевого элемента.Я также использую UIautomator2 в качестве своей автоматизации, поэтому не уверен, придется ли мне дольше ждать после переключения обратно в контекст веб-просмотра (код сценария 2, приведенный ниже).

Пока что единственные решения, которые я пробовал без обращения кto Thread.sleep (time), добавлял явные ожидания перед выбором приложения (сценарий 1) или поиском, если элемент будет вызывать findBy () (сценарий 2).

Случаи, которые я получаю со Сценарием 1, это то, что он, кажется, находит элемент, так как он выполняет метод click (), но он продолжает искать элемент и не может его найти, так как этот идентификатор больше не существуетсуществует после возобновления в приложении.Я заканчиваю тем, что получаю Исключение Тайм-аута или некоторые Исключения устаревшего элемента.Я не уверен, что использование другого метода внутри wait.until () решит проблему с поиском элемента, пока он не будет найден, а затем нажмите.

(Изменить) Код сценария 1: (Решено)

void viewActiveAppList() {

     driver.pressKey(new KeyEvent(AndroidKey.APP_SWITCH));
     driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}



void resumeApp(String appName){

    viewActiveAppList();
    driver.context("NATIVE_APP");
    MobileElement app = (MobileElement) wait.until(ExpectedConditions.elementToBeClickable(MobileBy.AccessibilityId(appName)));
    app.click();
    driver.context(defaultContext);
    wait.waitUntilPageLoaded();

}

Сценарий 2 Код:

swipeVertical:

void swipeVertical(double startPercentage, double finalPercentage, int duration) {
    driver.context(nativeContext);
    size = driver.manage().window().getSize();
    int width = (int) (size.width/2);
    int startPoint = (int) (size.getHeight() * startPercentage);
    int endPoint = (int) (size.getHeight() * finalPercentage);
    new AndroidTouchAction(driver)
        .press(PointOption.point(width, startPoint))
        .waitAction(WaitOptions.waitOptions(Duration.ofMillis(duration)))
        .moveTo(PointOption.point(width, endPoint))
        .release()
        .perform();
    driver.context(defaultContext);

}

swipeUntilFound:

void swipeUntilFound(By method, int attempts, MobileElement targetElement, Direction dir) {
    int limitCount = 0;
    double startScrollPoint = 0;
    double endScrollPoint = 0;
    switch (dir) {
        case up:
            startScrollPoint = 0.35;
            endScrollPoint = 0.8;
            break;
        case down:
            startScrollPoint = 0.8;
            endScrollPoint = 0.35;
            break;
    default:
        System.out.println("This method only supports directions up and down");
        break;
    }
    List<MobileElement> searchAfterSwipe = driver.findElements(method);
    while (searchAfterSwipe.isEmpty() || limitCount < attempts ) {
        swipeVertical(startScrollPoint, endScrollPoint, 3000);
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        searchAfterSwipe = driver.findElements(method);
        limitCount++;
    }
    if(limitCount == attempts) {
        System.out.println("Unable to find Specified Element.");
    }else {
        targetElement = driver.findElement(method);
        System.out.println("Element " + method.toString() + " was found.");
    }
}

(Правка) В первом сценарии я получал TimeoutExceptions иСписок устаревших элементов.Я смог решить эту проблему, переключившись на ExpectedConditions.elementToBeClickable (), поскольку мне нужно только найти этот элемент, пока он не станет активным.

Для сценария 2 ниже приведены журналы с моего удаленного сервера при захвате журналов.Я обрезал его до той части, где у меня возникают проблемы с тем, что я не могу найти элемент с тем способом, который я предоставляю.

[HTTP] [37m<-- POST /wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/elements [39m[32m200[39m [90m385 ms - 108[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/context[39m
[HTTP] [90m{"name":"NATIVE_APP"}[39m
[W3C (8fd3955f)] Calling AppiumDriver.setContext() with args: ["NATIVE_APP","8fd3955f-3ca9-4678-849f-8fac412a6347"]
[AndroidDriver] Available contexts: ["NATIVE_APP","CHROMIUM"]
[W3C (8fd3955f)] Responding to client with driver.setContext() result: null
[HTTP] [37m<-- POST /wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/context [39m[32m200[39m [90m79 ms - 14[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mGET[39m [37m/wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/window/rect[39m
[HTTP] [90m{}[39m
[W3C (8fd3955f)] Calling AppiumDriver.getWindowRect() with args: ["8fd3955f-3ca9-4678-849f-8fac412a6347"]
[WD Proxy] Matched '/window/current/size' to command name 'getWindowSize'
[WD Proxy] Proxying [GET /window/current/size] to [GET http://localhost:8200/wd/hub/session/a0f6efb1-b817-427c-8b44-c79af74b08fe/window/current/size] with body: {}
[WD Proxy] Got response with status 200: "{\"sessionId\":\"a0f6efb1-b817-427c-8b44-c79af74b08fe\",\"status\":0,\"value\":{\"height\":2560,\"width\":1440}}"
[W3C (8fd3955f)] Responding to client with driver.getWindowRect() result: {"width":1440,"height":2560,"x":0,"y":0}
[HTTP] [37m<-- GET /wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/window/rect [39m[32m200[39m [90m121 ms - 50[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/touch/perform[39m
[HTTP] [90m{"actions":[{"action":"press","options":{"x":720,"y":896}},{"action":"wait","options":{"ms":3000}},{"action":"moveTo","options":{"x":720,"y":2048}},{"action":"release","options":{}}]}[39m
[W3C (8fd3955f)] Calling AppiumDriver.performTouch() with args: [[{"action":"press","options":{"x":720,"y":896}},{"action":"wait","options":{"ms":3000}},{"action":"moveTo","options":{"x":720,"y":2048}},{"action":"release","options":{}}],"8fd3955f-3ca9-4678-849f-8fac412a6347"]
[WD Proxy] Matched '/touch/perform' to command name 'performTouch'
[WD Proxy] Proxying [POST /touch/perform] to [POST http://localhost:8200/wd/hub/session/a0f6efb1-b817-427c-8b44-c79af74b08fe/touch/perform] with body: {"startX":720,"startY":896,"endX":720,"endY":2048,"steps":84}
[WD Proxy] Got response with status 200: {"sessionId":"67b7b41cf15632508b04b6bfc48f62cd","status":0,"value":[{"ELEMENT":"0.6576757443982535-1"}]}
[WD Proxy] Replacing sessionId 67b7b41cf15632508b04b6bfc48f62cd with 2464c639-5ba7-49f5-842a-dadd77f4e596
[HTTP] [37m<-- POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/elements [39m[32m200[39m [90m5157 ms - 108[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/context[39m
[HTTP] [90m{"name":"NATIVE_APP"}[39m
[W3C (2464c639)] Calling AppiumDriver.setContext() with args: ["NATIVE_APP","2464c639-5ba7-49f5-842a-dadd77f4e596"]
[AndroidDriver] Available contexts: ["NATIVE_APP","CHROMIUM"]
[W3C (2464c639)] Responding to client with driver.setContext() result: null
[HTTP] [37m<-- POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/context [39m[32m200[39m [90m90 ms - 14[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mGET[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/window/rect[39m
[HTTP] [90m{}[39m
[W3C (2464c639)] Calling AppiumDriver.getWindowRect() with args: ["2464c639-5ba7-49f5-842a-dadd77f4e596"]
[WD Proxy] Matched '/window/current/size' to command name 'getWindowSize'
[WD Proxy] Proxying [GET /window/current/size] to [GET http://localhost:8201/wd/hub/session/16c2134a-84d5-4ca7-98d8-9cf96217376d/window/current/size] with body: {}
[WD Proxy] Got response with status 200: "{\"sessionId\":\"16c2134a-84d5-4ca7-98d8-9cf96217376d\",\"status\":0,\"value\":{\"height\":1794,\"width\":1080}}"
[W3C (2464c639)] Responding to client with driver.getWindowRect() result: {"width":1080,"height":1794,"x":0,"y":0}
[HTTP] [37m<-- GET /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/window/rect [39m[32m200[39m [90m283 ms - 50[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/touch/perform[39m
[HTTP] [90m{"actions":[{"action":"press","options":{"x":540,"y":627}},{"action":"wait","options":{"ms":3000}},{"action":"moveTo","options":{"x":540,"y":1435}},{"action":"release","options":{}}]}[39m
[W3C (2464c639)] Calling AppiumDriver.performTouch() with args: [[{"action":"press","options":{"x":540,"y":627}},{"action":"wait","options":{"ms":3000}},{"action":"moveTo","options":{"x":540,"y":1435}},{"action":"release","options":{}}],"2464c639-5ba7-49f5-842a-dadd77f4e596"]
[WD Proxy] Matched '/touch/perform' to command name 'performTouch'
[WD Proxy] Proxying [POST /touch/perform] to [POST http://localhost:8201/wd/hub/session/16c2134a-84d5-4ca7-98d8-9cf96217376d/touch/perform] with body: {"startX":540,"startY":627,"endX":540,"endY":1435,"steps":84}
[WD Proxy] Got response with status 200: {"sessionId":"a0f6efb1-b817-427c-8b44-c79af74b08fe","status":0,"value":true}
[W3C (8fd3955f)] Responding to client with driver.performTouch() result: true
[HTTP] [37m<-- POST /wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/touch/perform [39m[32m200[39m [90m11402 ms - 14[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/8fd3955f-3ca9-4678-849f-8fac412a6347/context[39m
[HTTP] [90m{"name":"CHROMIUM"}[39m
[W3C (8fd3955f)] Calling AppiumDriver.setContext() with args: ["CHROMIUM","8fd3955f-3ca9-4678-849f-8fac412a6347"]
[AndroidDriver] Available contexts: ["NATIVE_APP","CHROMIUM"]
[AndroidDriver] Connecting to chrome-backed webview context 'CHROMIUM'
[AndroidDriver] Found existing Chromedriver for context 'CHROMIUM'. Using it.
[WD Proxy] Matched '/url' to command name 'getUrl'
[WD Proxy] Proxying [GET /url] to [GET http://127.0.0.1:8001/wd/hub/session/aa3ae372d50348a0bbe746116f9e04b3/url] with no body
[WD Proxy] Got response with status 200: {"sessionId":"16c2134a-84d5-4ca7-98d8-9cf96217376d","status":0,"value":true}
[W3C (2464c639)] Responding to client with driver.performTouch() result: true
[HTTP] [37m<-- POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/touch/perform [39m[32m200[39m [90m13457 ms - 14[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/context[39m
[HTTP] [90m{"name":"CHROMIUM"}[39m
[W3C (2464c639)] Calling AppiumDriver.setContext() with args: ["CHROMIUM","2464c639-5ba7-49f5-842a-dadd77f4e596"]
[AndroidDriver] Available contexts: ["NATIVE_APP","CHROMIUM"]
[AndroidDriver] Connecting to chrome-backed webview context 'CHROMIUM'
[AndroidDriver] Found existing Chromedriver for context 'CHROMIUM'. Using it.
[WD Proxy] Matched '/url' to command name 'getUrl'
[WD Proxy] Proxying [GET /url] to [GET http://127.0.0.1:8000/wd/hub/session/67b7b41cf15632508b04b6bfc48f62cd/url] with no body
[WD Proxy] Got response with status 200: "{\"sessionId\":\"67b7b41cf15632508b04b6bfc48f62cd\",\"status\":0,\"value\":\"https://www.google.com/search?source=hp&ei=StWmXJXmJtHq-gTwkrqwBg&q=star+wars&oq=star+wars&gs_l=mobile-gws-wiz-hp.12..0i131j0j46i131j0j0i131j46i131j0j46.10902.22037..27071...0.0..0.1451.6075.2-2j3j1j1j1j2......0....1.......0..46i275.inyUIvu9Es8\"}"
[W3C (2464c639)] Responding to client with driver.setContext() result: null
[HTTP] [37m<-- POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/context [39m[32m200[39m [90m13084 ms - 14[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/timeouts[39m
[HTTP] [90m{"implicit":30000}[39m
[W3C (2464c639)] Driver proxy active, passing request on via HTTP proxy
[WD Proxy] Matched '/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/timeouts' to command name 'timeouts'
[Protocol Converter] Will send the following request bodies to /timeouts: [{"type":"implicit","ms":30000}]
[WD Proxy] Proxying [POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/timeouts] to [POST http://127.0.0.1:8000/wd/hub/session/67b7b41cf15632508b04b6bfc48f62cd/timeouts] with body: {"type":"implicit","ms":30000}
[WD Proxy] Got response with status 200: {"sessionId":"67b7b41cf15632508b04b6bfc48f62cd","status":0,"value":null}
[WD Proxy] Replacing sessionId 67b7b41cf15632508b04b6bfc48f62cd with 2464c639-5ba7-49f5-842a-dadd77f4e596
[HTTP] [37m<-- POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/timeouts [39m[32m200[39m [90m165 ms - 76[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/elements[39m
[HTTP] [90m{"using":"name","value":"q"}[39m
[W3C (2464c639)] Driver proxy active, passing request on via HTTP proxy
[WD Proxy] Matched '/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/elements' to command name 'findElements'
[WD Proxy] Proxying [POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/elements] to [POST http://127.0.0.1:8000/wd/hub/session/67b7b41cf15632508b04b6bfc48f62cd/elements] with body: {"using":"name","value":"q"}
[WD Proxy] Got response with status 200: {"sessionId":"67b7b41cf15632508b04b6bfc48f62cd","status":0,"value":[{"ELEMENT":"0.5466260018440561-1"}]}
[WD Proxy] Replacing sessionId 67b7b41cf15632508b04b6bfc48f62cd with 2464c639-5ba7-49f5-842a-dadd77f4e596
[HTTP] [37m<-- POST /wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/elements [39m[32m200[39m [90m507 ms - 108[39m
[HTTP] [90m[39m
[HTTP] [37m-->[39m [37mPOST[39m [37m/wd/hub/session/2464c639-5ba7-49f5-842a-dadd77f4e596/context[39m
...