首页 文章

Web应用程序中的Appium:无法在通知弹出窗口中点击“允许权限”按钮

提问于
浏览
2

当我打开网络应用程序时,我正在弹出一个 . 我试图以两种方式点击“允许”按钮:

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

我发现这篇文章:Unable to tap the link after tap on Allow button of permission alert in Appium?但它没有帮助我 .

3 回答

  • 4

    第一: capabilities 你试图用 IOS only

    在Android上你必须通过 findElement 找到弹出窗口并自己关闭它们 .

    第二:自从你为 web application 开始Appium会话之后,在搜索原生弹出窗口之前你 must switch the context

    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();
    

    不要忘记将上下文切换回web以继续:

    driver.context(webContext);
    
  • 1

    我有类似自己的问题,这是我如何解决这个问题:

    这是来自我的页面对象的代码的一部分,当点击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) {
    
        }
    }
    

    忽略屏幕扩展,只需尝试使用现有Alert(org.openqa.selenium.Alert包)的实现 .

    我知道这不是解决方案1:1您必须调整它,以便合并到您的代码中,但重点是尝试覆盖Alert并等待元素出现,并与之交互 .

    希望这会对你有所帮助,

  • 2

    尝试设置这样的功能:

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

    如果它没有用,请尝试使用此xPath找到“ALLOW”按钮:

    //*[. = '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 中 . 这就是在脚本中添加wait非常有用的原因 .

    对于 WebDriverWait ,您必须添加一些导入:

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

相关问题