TL;DR: Ask yourself if you really need to do all the stuff below for your test. Why, exactly, do you need your second test to run on your second emulator?
(All of this would also be much easier if Selenium checked the deviceName capability as part of its matching process by default)
The following is all an example.
First, build your custom capability matcher. As an example, suppose you want to build a capability matcher to distinguish between emulators and real devices, and you want to distinguish between the two using your own capability type called "isEmulator":
- Create a Java project, ideally using Maven or Gradle.
- Declare a dependency on org.seleniumhq.selenium:selenium-server:2.52.0
- Create a class that implements the CapabilityMatcher interface, that has your own custom node matching logic. The logic is to checks whether the requested capabilities has an "isEmulator" field; if this field exists, return true only for a node that has this provided capability and matches the value in the desired capability.
- Build the project. You should get a JAR file as the output.
Now, when you start your Selenium Hub, you want to include your JAR file in the classpath for the Java process, and specify your CapabilityMatcher implementation as the capability matcher for the server to use. As an example, my launch command for Selenium Grid with my capability matcher looks like the following:
java -cp selenium-server-standalone-2.53.0.jar:MY-JAR-FILE \
org.openqa.grid.selenium.GridLauncher -role hub \
-capabilityMatcher com.sample.afwang.MyCapabilityLauncher
Next, when I run my tests, I can add in additional capabilities that MyCapabilityLauncher will use to determine whether a node matches or not.
On the test node side, I also specify some provided capabilities the test node provides. My Appium nodeconfig file looks something a bit like:
{
"capabilities": [
{
"version": "4.4.4"
"maxInstances": "1"
"platform": "Android",
"isEmulator": "yes"
}
],
//blah blah blah, other various configuration items.
}
Now when I start my Appium node, it'll register itself with the Selenium Hub with the given capabilties, so now the Hub will know that this node provides an "isEmulator" field, and this field's value's is "yes".
In your test script, when you set up your desired capabilities, I would specify something like this:
desired_caps['isEmulator'] = 'yes'
Now when I start a driver, Selenium will use my matcher to check for the isEmulator field, and ensures that the requested capability and the provided capability from my Appium node matches.
I have to try to summarize a lot of content. There's quite a bit of information condensed here, so take it slow and work diligently on each part until you get to the end. If you don't know Java, you'll have to pick up a bit of it to write your capability matcher, and understand how classpaths work.
You should also ask yourself one more question to save yourself all this trouble: Why do you need to have your second test run on the second emulator? If they have the same platform and version, do you really care about testing among the less significant variable differences between your emulators?