How to make sure the appium node is connected to o

2019-08-04 16:50发布

问题:

I run (all on one machine) multiple appium servers connected as nodes to a selenium-grid hub and I have multiple phones connected to my adb on port 5555 (in my case via WiFi).

The issue I have with this is that two of the three phones have capabilities that are matching (Android 7.1.1, Chrome browser). So when I fire up a test for the nexus 9, if occupies the grid node for nexus 6. Or even the other way around, I ask to run the test on the nexus 6, this one get occupied, but the test runs on the nexus 9. So what I want/need is a configuration I can use to make it unique enough to fire up an appium server that only connects to one phone.

My setup

  • Windows 10 (x64)
  • Ruby v2.3.3 (32 bit) with the gems watir v6.8.4, selenium-webdriver v3.6.0
  • Selenium-Standalone-Server v3.6.0
  • Appium Desktop v1.2.5 (server v1.7.1)
  • Or via command line Appium server v1.6.5

Test devices

  • Nexus 5 (phone)- Android 6.0.1 - 192.1.1.120:5555 (in adb devices list)
  • Nexus 6 (phone)- Android 7.1.1 - 192.1.1.63:5555 (in adb devices list)
  • Nexus 9 (tablet)- Android 7.1.1 - 192.1.1.55:5555 (in adb devices list)

Grid

java -jar selenium-standalone-server3.6.0.jar -role hub

Start the appium servers via the command line (or desktop app)

appium -a 0.0.0.0 -p 4723 -bp 4724 --nodeconfig node_nexus5.json

appium -a 0.0.0.0 -p 4725 -bp 4726 --nodeconfig node_nexus6.json

appium -a 0.0.0.0 -p 4727 -bp 4728 --nodeconfig node_nexus9.json

node_nexus6.json (node 5 and 9 are only different in platformVersion, deviceName, udid and applicationName)

{
  "capabilities":[
    {
    "platform": "ANDROID",
    "platformName": "Android",
    "platformVersion": "7.1.1",
    "browserName": "chrome",
    "version": "6",
    "deviceName": "Nexus6",
    "udid": "192.1.1.63:5555",
    "applicationName": "Nexus6",
    "maxInstances": 1
    }
  ],
  "configuration":
    {
    "cleanUpCycle":2500,
    "timeout":30000,
    "maxSession": 1,
    "register": true,
    "registerCycle": 1000,
    "hubPort": 4444,
    "hubHost": "localhost"
    }
}

What I tried

The deviceName, applicationName, version capability

browser = Watir::Browser.new :chrome, {
    url: "http://localhost:4444/wd/hub",  
    platformName: "Android",
    platformVersion: "7.1.1",
    browserName: "chrome",
    version: "6",
    deviceName: "Nexus6",
    applicationName: "Nexus6"
}

Results

When only using the device name, the result was the weirdest. On the grid the nexus 6 was being occupied. But I saw the server I wanted to respond to the nexus 5 to take the job, but it got executed on the nexus 9

When I included the applicationName, the correct grid node was occupied (nexus 6), the appium server I thought was going to respond did respond, but it again executed the test on the nexus 9 device.

Version did the same as applicationName.

Udid I did not try because it will just overwrite this capability like a timeout.

The main question

How can I configure the appium server node to only serve one specific phone without the need for writing a custom capability matcher?

回答1:

I was surprised that the capabilities I tries before did not work since in other forum posts it seemed to have worked for others (although usually not clear if they use a selenium-grid).

My solution so far is to use the following appium server (grid node) config (both udid and version need to be included)

{
  "capabilities":[
    {
    "platform": "ANDROID",
    "platformName": "Android",
    "platformVersion": "7.1.1",
    "browserName": "chrome",
    "version": "6",
    "deviceName": "Nexus6",
    "udid": "192.1.1.63:5555",
    "maxInstances": 1
    }
  ],
  "configuration":
    {
    "cleanUpCycle":2500,
    "timeout":30000,
    "maxSession": 1,
    "register": true,
    "registerCycle": 1000,
    "hubPort": 4444,
    "hubHost": "localhost"
    }
}

And for starting the session the same applies (include udid and version)

Watir::Browser.new :chrome, {
    url: "http://localhost:4444/wd/hub",  
    platformName: "Android",
    platformVersion: "7.1.1",
    browserName: "chrome",
    version: "6",
    deviceName: "Nexus6",
    udid: "192.1.1.63:5555"
}

It would still be good to know why the above solutions I tried did not work. From all things I did read I assume this is the reason. The grid only looks at platformName, platformVersion, browserName, version(browserVersion) and deviceName (although this last one is being ignored). Based on that it will forward all capabilities to a matching appium node. Then udid is recognized as a capability by the appium node and used to make a connection to the phone I want. If I leave out the udid, it will connect to a phone that is matching the other capabilities and ignores the udid I set in the initial config. That last is what I don't understand why this is the case, but for me this setup (with udid) works.