无法使用 AWS 设备场打开和关闭通知面板

Posted

技术标签:

【中文标题】无法使用 AWS 设备场打开和关闭通知面板【英文标题】:Unable to open and close notifications panel with AWS Device farm 【发布时间】:2018-10-14 18:31:44 【问题描述】:

我的测试需要打开和关闭通知面板,然后从 android 设备(Moto G4 Android 7 - AWS 设备场)返回应用程序。所以我在我的测试中调用了以下方法

androidActivity.openAndCloseNotifications();

在哪里

public void openAndCloseNotifications() throws InterruptedException 
    TimeUnit.SECONDS.sleep(3);
    driver.openNotifications();
    TimeUnit.SECONDS.sleep(3);
    driver.pressKeyCode(AndroidKeyCode.BACK);          
 

测试通过设备在本地通过,但是当我在 AWS 设备场上运行它时,我可以看到通知面板永远不会打开,因此测试失败。 此时 AWS 设备场是否允许与通知面板交互?如果没有,我该如何处理?因为这对于我们的大多数测试来说都是一个问题。 提前致谢!

这是失败的测试,在androidActivity.openAndCloseNotifications(); 行失败:

    public boolean run() throws Exception 
    MainActivity mainActivity = new MainActivity(driver);
    AndroidActivity androidActivity = new AndroidActivity(driver);
    LoginActivity loginActivity = new LoginActivity(driver);



    try 
    if(device.getCapability("manufacturer")=="Huawei")
     
        driver.closeApp();
        driver.launchApp();
        loginActivity.registerApp("whateverhere");
        androidActivity.openAndCloseNotifications();
        mainActivity.verifyAppIsReady();
        assertTrue(mainActivity.check());
        return true;

    

    else 

        driver.closeApp();
        driver.launchApp();
        loginActivity.registerApp("whateverhere");
        androidActivity.openAndCloseNotifications();
        mainActivity.verifyAppIsReady();
        System.out.println("Verified Stop button is displayed");
        assertTrue(mainActivity.check());
        System.out.println("Verified title is displayed");
        return true;
        
    

    catch(Exception e) 
        System.out.println(e);
        return false;
    


来自 AWS 设备场的日志(本地没有故障) java.lang.AssertionError: 预期 [true] 但发现 [false]\n\tat org.testng.Assert.fail(Assert.java:94)\n\tat org.testng.Assert.failNotEquals(Assert.java:494 )\n\tat org.testng.Assert.assertTrue(Assert.java:42)\n\tat org.testng.Assert.assertTrue(Assert.java:52)\n\tat com.OneMeter.Robirdo.TestSequence1.test1 (TestSequence1.java:48)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\n\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)\n\tat sun.reflect.DelegatingMethodAccessorImpl。调用(DelegatingMethodAccessorImpl.java:43)\n\tat java.lang.reflect.Method.invoke(Method.java:498)\n\tat org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)\n \tat org.testng.internal.Invoker.invokeMethod(Invoker.java:714)\n\tat org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)\n\tat org.testng.internal.Invoker。 invokeTestMethods(Invoker.java:1231)\n\tat org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodW orker.java:127)\n\tat org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)\n\tat org.testng.TestRunner.privateRun(TestRunner.java:767)\n\tat org. testng.TestRunner.run(TestRunner.java:617)\n\tat org.testng.SuiteRunner.runTest(SuiteRunner.java:348)\n\tat org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)\n \tat org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)\n\tat org.testng.SuiteRunner.run(SuiteRunner.java:254)\n\tat org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java: 52)\n\tat org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)\n\tat org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)\n\tat org.testng.TestNG.runSuitesLocally( TestNG.java:1149)\n\tat org.testng.TestNG.run(TestNG.java:1057)\n\tat org.testng.TestNG.privateMain(TestNG.java:1364)\n\tat org.testng。 TestNG.main(TestNG.java:1333)\n\n

【问题讨论】:

能否提供appium服务器日志和打印页面源的测试输出? 我已经添加了您要求的所有内容。本地一切都很好。 还应该有来自 Device Farm 的 appum 服务器输出日志。您也可以使用该日志更新它吗?它将显示调用 openNotifications 方法时究竟发生了什么。 【参考方案1】:

用 OnePlus 3T 在本地测试,结果很成功

能力:

capabilities.setCapability("app", "C:\\Users\\james\\Desktop\\***\\question_50172058_unable-to-open-and-close-notifications-panel-with-aws-device-farm\\testofopenNotifications\\app-debug.apk");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", "OnePlus");

Appium 版本:1.7.1

Appium 服务器输出:

[info] [HTTP] --> POST /wd/hub/session/51cf9f0e-2106-4e34-b0d5-7df3caebc223/appium/device/open_notifications 
[debug] [MJSONWP] Calling AppiumDriver.openNotifications() with args: ["51cf9f0e-2106-4e34-b0d5-7df3caebc223"]
[debug] [AndroidBootstrap] Sending command to android: "cmd":"action","action":"openNotification","params":[debug] [AndroidBootstrap] Received command result from bootstrap
[debug] [MJSONWP] Responding to client with driver.openNotifications() result: true
[info] [HTTP] <-- POST /wd/hub/session/51cf9f0e-2106-4e34-b0d5-7df3caebc223/appium/device/open_notifications 200 328 ms - 76 

使用 example tests 中的程序集和 pom 打包测试后,使用命令 mvn clean package -DskipTests=true 这是使用 Moto G4 Android 7 的设备场的结果:

Appium 服务器版本:1.7.1 如here 所述,使用了一个空的所需功能对象

成功并打开通知。 See video

Appium 服务器日志:

2018-05-05 16:55:06:839 - [HTTP] --> POST /wd/hub/session/c70b3b24-b7d6-4c6b-a7e2-d4ff5e91aa22/appium/device/open_notifications 
2018-05-05 16:55:06:868 - [debug] [MJSONWP] Calling AppiumDriver.openNotifications() with args: ["c70b3b24-b7d6-4c6b-a7e2-d4ff5e91aa22"]
2018-05-05 16:55:06:872 - [debug] [AndroidBootstrap] Sending command to android: "cmd":"action","action":"openNotification","params":
2018-05-05 16:55:06:888 - [debug] [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: "cmd":"action","action":"openNotification","params":
2018-05-05 16:55:06:889 - [debug] [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
2018-05-05 16:55:06:890 - [debug] [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: openNotification
2018-05-05 16:55:06:891 - [debug] [AndroidBootstrap] Received command result from bootstrap
2018-05-05 16:55:06:893 - [debug] [MJSONWP] Responding to client with driver.openNotifications() result: true
2018-05-05 16:55:06:907 - [HTTP] <-- POST /wd/hub/session/c70b3b24-b7d6-4c6b-a7e2-d4ff5e91aa22/appium/device/open_notifications 200 55 ms - 76 

这是我执行的测试方法:

@Test public void testOpenNotifications()
        //docs: https://github.com/appium/appium/blob/62700d3b1dc0edd985502cc1279747a782f3ee74/docs/en/commands/device/system/open-notifications.md
        driver.openNotifications();
    

我认为调用 sleep 的代码可能会导致问题,但它似乎也可以正常工作。见video

代码:

@Test public void testOpenNotificationsWithSleep() throws InterruptedException
        TimeUnit.SECONDS.sleep(3);
        driver.openNotifications();
        TimeUnit.SECONDS.sleep(3);
    

能否分享您在 Device Farm 中执行的 appium 服务器日志?它将显示来自 UIAutomator 或 UIAutomator2 的响应,我们可以从那里开始。

这是我的完整测试类进行比较:

package Tests;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;

public class OpenNotificationsTest

     /**
     * Make the driver static. This allows it to be created only once
     * and used across all of the test classes.
     */
    public static AndroidDriver<MobileElement> driver;

    /**
     * This method runs before any other method.
     *
     * Appium follows a client - server model:
     * We are setting up our appium client in order to connect to Device Farm's appium server.
     *
     * We do not need to and SHOULD NOT set our own DesiredCapabilities
     * Device Farm creates custom settings at the server level. Setting your own DesiredCapabilities
     * will result in unexpected results and failures.
     *
     * @throws MalformedURLException An exception that occurs when the URL is wrong
     */
    @BeforeSuite
    public void setUpAppium() throws MalformedURLException 

        final String URL_STRING = "http://127.0.0.1:4723/wd/hub";

        URL url = new URL(URL_STRING);

        //Use a empty DesiredCapabilities object fro device farm
        DesiredCapabilities capabilities = new DesiredCapabilities();

        //local capabilities
        capabilities.setCapability("app", "C:\\Users\\james\\Desktop\\***\\question_50172058_unable-to-open-and-close-notifications-panel-with-aws-device-farm\\testofopenNotifications\\app-debug.apk");
        capabilities.setCapability("platformName", "Android");
        capabilities.setCapability("deviceName", "OnePlus");

        driver = new AndroidDriver<MobileElement>(url, capabilities);

        //Use a higher value if your mobile elements take time to show up
        driver.manage().timeouts().implicitlyWait(35, TimeUnit.SECONDS);
    

    @Test public void testOpenNotifications()
        //docs: https://github.com/appium/appium/blob/62700d3b1dc0edd985502cc1279747a782f3ee74/docs/en/commands/device/system/open-notifications.md
        driver.openNotifications();
    

    @Test public void testOpenNotificationsWithSleep() throws InterruptedException
        TimeUnit.SECONDS.sleep(3);
        driver.openNotifications();
        TimeUnit.SECONDS.sleep(3);
    

    /**
     * Always remember to quit
     */
    @AfterSuite
    public void tearDownAppium() 
        driver.quit();
    

    /**
     * Restart the app after every test class to go back to the main
     * screen and to reset the behavior
     */
    @AfterClass
    public void restartApp() 
        driver.resetApp();
    

希望很快收到您的来信。

-詹姆斯

【讨论】:

我刚刚回复了你的帖子,还是有点迷失在***上。【参考方案2】:

在设备场中似乎没有驱动程序的appium服务器日志。openNotifications(); (无论如何都要附上它们)。

使用 appium 1.7.2 不确定这是否是问题,我根据您的示例稍微修改了我的代码,我仍然可以重现相同的问题,没有打开通知。

在下面找到我的代码(请注意,有 2 个测试,它们以这种方式完成是为了强制 AWS 按顺序运行它们,因为它忽略了一些 testNG 注释)

public class TestSequence1 
public int global1;
public DesiredCapabilities capabilities;
public static AndroidDriver<MobileElement> driver;
private Factory1 testfactory;

@BeforeSuite
public void setUp() throws MalformedURLException 
    capabilities = new DesiredCapabilities();
    global1 = 0;
    URL appiumURL = new URL("http://127.0.0.1:4723/wd/hub");
    capabilities.setCapability("appPackage", "MyAppPackage");
    capabilities.setCapability("appActivity", "MyAppActivity");
    capabilities.setCapability("platformName", "Android");
    capabilities.setCapability("deviceName", "MotoG4");
    //capabilities.setCapability("manufacturer", manufacturer);
    //capabilities.setCapability("noReset", true);
    driver = new AndroidDriver<MobileElement>(appiumURL, capabilities);
    testfactory = new Factory1(capabilities, driver);



@Test
public void test1() throws Exception 

    Tests.Test test=testfactory.getNextTest();
    boolean returnvalue = test.run();
    assertTrue(returnvalue);



@Test
public void test2() throws Exception 

    Tests.Test test=testfactory.getNextTest();
    boolean returnvalue = test.run();
    assertTrue(returnvalue);





@AfterSuite
public void tearDown() 
    driver.quit();


@AfterClass
public void restartApp() 
    driver.resetApp();

在哪里:

public Factory1(DesiredCapabilities Capabilities, AndroidDriver<MobileElement> Driver) 

    device = Capabilities;
    driver =Driver;
    testNumber=0;



public Factory1() 
    // TODO Auto-generated constructor stub


public Tests.Test getNextTest() 

    if(testNumber==0)
    
        test = new BasicTest1(device, driver);
    
    else if(testNumber==1)
    
        test = new BasicTest2(device, driver);
    

    testNumber++;
    return test;

失败的测试如下:

public class BasicTest2 extends Tests.Test
public DesiredCapabilities device;
public AndroidDriver<MobileElement> driver;



public BasicTest2(DesiredCapabilities capabilities, AndroidDriver<MobileElement> driver) 
    device = capabilities;
    this.driver = driver;



public boolean run() throws Exception 
    MainActivity mainActivity = new MainActivity(driver);
    AndroidActivity androidActivity = new AndroidActivity(driver);
    LoginActivity loginActivity = new LoginActivity(driver); 

 try   driver.closeApp();
        driver.launchApp();
        loginActivity.registerApp("password");
        androidActivity.openAndCloseNotifications();
        mainActivity.verifyAppIsReady();
        System.out.println("Verified Stop button is displayed");
        assertTrue(mainActivity.check());
        System.out.println("Verified title is displayed");
        return true;

    

    catch(Exception e) 
        System.out.println(e);
        return false;
    

`

我真的不知道出了什么问题,因为测试在少数具有不同 android 版本的设备上本地通过。 感谢您的帮助詹姆斯 :)

【讨论】:

如果您在该页面上向下滚动更多内容,则应该有一个指向 appium 服务器日志的链接。如果可以,请附上。

以上是关于无法使用 AWS 设备场打开和关闭通知面板的主要内容,如果未能解决你的问题,请参考以下文章

无法读取 aws 设备场中的属性文件

Quickblox:无法获得推送通知

电脑显示此设备上的蓝牙无法使用?

联想小新air15进入ubuntu无法用鼠标

如何在 aws sns 中注册 iOS 设备令牌以接收推送通知?

手机不能下滑控制面板