Appium в веб-приложении: невозможно нажать кнопку «Разрешить разрешение» во всплывающем окне уведомлений - PullRequest
0 голосов
/ 04 июля 2018

Когда я открываю веб-приложение, я получаю всплывающее окно. Я пытаюсь нажать кнопку «РАЗРЕШИТЬ» двумя способами:

1) Когда я добавляю разрешения:

caps.setCapability("autoGrantPermissions", true);
caps.setCapability("autoAcceptAlerts", true);
......
driver.switchTo().alert().accept();

ничего не происходит ((

2) Когда я пытаюсь найти его по XPath:

driver.findElement(By.xpath("//android.widget.Button[@text='Allow']")).click();

Я получаю сообщение об ошибке:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//android.widget.Button[@text='Allow']"}

Это мой скриншот из UI Automator Viewer:

enter image description here

Я нашел это сообщение: Невозможно нажать на ссылку после нажатия на кнопку Разрешить оповещение о разрешении в Appium? но это мне не помогло.

Ответы [ 3 ]

0 голосов
/ 09 июля 2018

Первый: возможности , которые вы пытались использовать, предназначены для только для IOS

На Android вы должны найти всплывающее окно через findElement и закрыть их самостоятельно .

Второе: поскольку вы запускаете сессию Appium для веб-приложения , перед поиском собственных всплывающих окон необходимо переключить контекст :

    String webContext = driver.getContext();
    Set<String> contexts = driver.getContextHandles();
    for (String context: contexts){
        if (context.contains("NATIVE_APP")){
            driver.context(context);
            break;
        }
    }
    driver.findElement(By.id("android:id/button1")).click();

Не забудьте переключить контекст обратно в сеть, чтобы продолжить:

    driver.context(webContext);
0 голосов
/ 09 июля 2018

У меня была похожая проблема, как и у вас, вот как я решил это:

Это часть кода из объекта моей страницы, где при нажатии на useGPS отображается собственное уведомление Android, разрешающее или блокирующее использование GPS,

public Alert clickButtonUseGPSwithAlert() {
    buttonUseGps.click();
    Validate.action(getSessionInfo(), "click button 'Use a GPS'");
    Alert alert = new Alert(getSessionInfo());
    return alert;
}

и вот переопределенный класс Alert,

import io.appium.java_client.MobileElement;
import io.appium.java_client.pagefactory.AndroidFindBy;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.pagefactory.WithTimeout;
import org.openqa.selenium.support.PageFactory;
import pageObjects.Screen;
import utils.Validate;
import java.util.concurrent.TimeUnit;

public class Alert extends Screen implements org.openqa.selenium.Alert {
    @AndroidFindBy(id = "com.android.packageinstaller:id/dialog_container")
    @WithTimeout(time = 3, unit = TimeUnit.SECONDS)
    public MobileElement alertControl;

    @AndroidFindBy(id = "com.android.packageinstaller:id/permission_message")
    @WithTimeout(time = 3, unit = TimeUnit.SECONDS)
    private MobileElement content;

    @AndroidFindBy(id = "com.android.packageinstaller:id/permission_allow_button")
    @WithTimeout(time = 3, unit = TimeUnit.SECONDS)
    private MobileElement buttonAccept;

    @AndroidFindBy(id = "com.android.packageinstaller:id/permission_deny_button")
    @WithTimeout(time = 3, unit = TimeUnit.SECONDS)
    private MobileElement buttonDismiss;


    public Alert(SessionInfo sessionInfo){
        super(sessionInfo);
        PageFactory.initElements(new AppiumFieldDecorator(sessionInfo.getMobileDriver(), 3, TimeUnit.SECONDS), this);

        WaitUtils.isElementPresent(sessionInfo.getMobileDriver(),alertControl,2);

        if (!Util.areElementsLoaded(alertControl, content, buttonAccept, buttonDismiss)) {
            setLoaded(false);
        } else {
            setLoaded(true);
        }
        Validate.isScreenLoaded(getSessionInfo(), this.isLoaded());

    }

    @Override
    public void dismiss() {
        buttonDismiss.click();
        Validate.action(getSessionInfo(), "ALERT - click button 'Dismiss'");
    }

    @Override
    public void accept() {
        buttonAccept.click();
        Validate.action(getSessionInfo(), "ALERT - click button 'Accept'");
    }

    @Override
    public String getText() {
        String value = content.getText();
        Validate.action(getSessionInfo(), "ALERT - get content");
        return value;
    }

    @Override
    public void sendKeys(String s) {

    }
}

Игнорировать расширение экрана, попробуйте использовать реализацию существующего оповещения (пакет org.openqa.selenium.Alert).

Я знаю, что это не решение 1: 1 Вы должны настроить его, чтобы включить в свой код, но главное - попытаться переопределить Alert и дождаться появления элемента, а затем взаимодействовать с ним.

Надеюсь, это поможет Вам,

0 голосов
/ 08 июля 2018

Попробуйте установить следующие возможности:

caps.setCapability("autoDismissAlerts", true);
caps.setCapability("autoGrantPermissions", true);
caps.setCapability("autoAcceptAlerts", true);
......
driver.switchTo().alert().accept();

Если это не поможет, попробуйте найти кнопку «РАЗРЕШИТЬ», используя этот xPath:

//*[. = 'Allow']

или

//*[contains(text(), 'Allow')]

или

//*[contains(text(), 'ALLOW')]

или

driver.findElement(By.id("com.android.chrome:id/button1")).click();

Также вы можете попытаться найти эту кнопку, открыв свое приложение в браузере, затем в инструментах разработчика найдите селектор этой кнопки и используйте его в Appium.

PS: добавьте WebDriverWait в свой код:

new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[. = 'Allow']"))).click();

Это подождет не менее 10 секунд, пока элемент не будет активирован. Иногда сценарий очень быстрый, и DOM на данный момент не содержит элемента, с которым вы хотите взаимодействовать. Так что вам придется подождать некоторое время, пока элемент окажется в DOM. Вот почему очень полезно добавить ожидание в ваш скрипт.

Для WebDriverWait необходимо добавить несколько импортов:

import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
...