Хай. Как на 6м андрюхе Апиумом заавтоматить setPermissions?
Потому что на никак не могу без “ручного” подтверждения доступа ранит тесты:
Капабилити autoAcceptAlerts=true
не помогает?
Неа. Пробовал. Да и, если не ошибаюсь, это же для яблофонов капабилитя?
Средствами аппиума можно прокликивать. Мы создавали отдельный виджет для этого попапа и в течении заданного интервала прокликивали allow
, пока он не пропадал.
Костылем подперлы?)) Как по мне то это не выход.
Код можно посмотреть?
Я сделал так:
PageObject:
public class PermissionForm extends Screen{
public PermissionForm(WebDriver appiumDriver) {
super(appiumDriver);
}
@FindBy(how = How.ID, using = "permission_allow_button")
private WebElement allowButton;
@FindBy(how = How.ID, using = "permission_message")
private WebElement getPermissionText;
public void allowPermission(){
AllureLogger.logToAllure("Allow next permission" + getPermissionText.getText());
allowButton.click();
}
public boolean isFormIsVisible(){
return getPermissionText.isDisplayed();
}
}
setup method in @BeforeSuite
@BeforeSuite
@Parameters({"platformVersion", "mobileDeviceName"})
public void setup(String platformVersion,
String mobileDeviceName)
throws Exception {
String timeout = PropertyLoader.loadProperty("timeout.implicit");
String appType = PropertyLoader.loadProperty("appium.app.type");
appiumDriver = AppiumDriverFactory.getAppiumDriver(platformVersion, mobileDeviceName);
appiumDriver.manage().timeouts().implicitlyWait(Integer.valueOf(timeout), TimeUnit.SECONDS);
PermissionForm permissionForm = PageFactory.initElements(appiumDriver, PermissionForm.class);
if (platformVersion.contains("6.0") && permissionForm.isFormIsVisible()){
permissionForm.allowPermission();
Thread.sleep(2000);
permissionForm.allowPermission();
}
Самый простой вариант - это собирать приложение с target SDK = 22, если это возможно. Тогда permissions не будут запрашиваться.
Ну почему же костылем? Если юзер видит этот попап, и от него нельзя так просто избавиться, как в случае с SDK < 22, то что тут еще обсуждать? Надо просто закрывать и продолжать работу.
Следующий код будет кликать по кнопке, пока она не пропадет (диалог может появляться несколько раз подряд), или не сработает глобальный таймаут.
@Getter
public class PermissionPopup extends Widget {
@AndroidFindBy(id = "permission_allow_button")
private MobileElement buttonAllow;
protected PermissionPopup(final WebElement element) {
super(element);
}
public void allow(final BiFunction<MobileElement, Long, Boolean> waitCondition) {
await().atMost(ELEMENT_WAIT_TIMEOUT, TimeUnit.SECONDS)
.pollInterval(POLLING_INTERVAL, TimeUnit.SECONDS)
.ignoreExceptions()
.until(() -> {
final boolean isVisible = waitCondition.apply(buttonAllow, ELEMENT_DISPLAY_TIMEOUT);
if (isVisible)
buttonAllow.click();
return !isVisible;
});
}
}
Поведение ожидания элемента можно параметризовать чем угодно. К примеру:
permissionsPopup.allow(this::isElementDisplayed);
У меня какаято лажа получается:
PermissionPopup.class
public PermissionPopup(WebDriver appiumDriver) {
super(appiumDriver);
}
@FindBy(how = How.ID, using = "permission_allow_button")
private WebElement buttonAllow;
@FindBy(how = How.ID, using = "permission_message")
private WebElement getPermissionText;
public void allow(final BiFunction<WebElement, Long, Boolean> waitCondition) throws FileNotFoundException {
await().until(() -> {
final boolean isVisible = waitCondition.apply(buttonAllow, Long.valueOf(10));
if (isVisible)
buttonAllow.click();
return !isVisible;
});
}
public void allowAllPermissions() throws FileNotFoundException {
allow(this::isFormIsVisible);
}
private Boolean isFormIsVisible(WebElement webElement, Long aLong) {
return getPermissionText.isDisplayed();
}
Стектрейс:
org.awaitility.core.ConditionTimeoutException: Condition with utility.PermissionPopup was not fulfilled within 10 seconds.
В моем примере задан глобальный таймаут для всех попапов, который контролируется через вызов atMost
. Т.е. он должен быть больше локального таймаута для единственного элемента, проверяющегося в until
.
Если вы явно не задаете глобальный таймаут, то используется дефолтный - 10 сек. Т.к. у вас дефолтный равен локальному, то независимо от результата операции в until
, вы в любом случае получаете timeout exception.
это не возможно. Да и подстраивать код ПО под тесты, как по мне - плохой варик…
Все, я поплыл … Сделал все так как у Вас:
public void allow(final BiFunction<WebElement, Long, Boolean> waitCondition) throws FileNotFoundException {
Long waitTimeOut = 20L;
Long pollingInterval = 5L;
Long elementDisplayTimeout = 20L;
await().atMost(waitTimeOut, TimeUnit.SECONDS)
.pollInterval(pollingInterval, TimeUnit.SECONDS)
.ignoreExceptions()
.until(() -> {
final boolean isVisible = waitCondition.apply(buttonAllow, elementDisplayTimeout);
if (isVisible)
buttonAllow.click();
return !isVisible;
});
}
public void allowAllPermissions() throws FileNotFoundException {
allow(this::isFormIsVisible);
}
private Boolean isFormIsVisible(WebElement webElement, Long aLong) {
return getPermissionText.isDisplayed();
}
Глобальний таймаут равен 15 секундам:
timeout.implicit=15
---
String timeout = PropertyLoader.loadProperty("timeout.implicit");
appiumDriver.manage().timeouts().implicitlyWait(Integer.valueOf(timeout), TimeUnit.SECONDS);
-
waitTimeout
должен быть большеelementDisplayTimeout
; к слову, он у вас вообще не задействован; я хоть и не показал, но в моем примере этот таймаут использовался для explicit waits, потому собственно и передаваласьBiFunction
; при вашем подходе достаточноFunction<WebElement, Boolean>
; -
implicitWait
будет лочить выполнениеuntil
на <=15 сек, что естественно повлияет и на глобальный таймаут.