Is it possible to use karate with AWS device farm for Android and iOS testing?

519 Views Asked by At

I'd like to know if it is possible to use karate with AWS device farm for Android and iOS testing. If this is possible, are there any example of configuration somewhere ?

The only thing related to karate and AWS device farm I can find is this repository but it's about web application testing.

Thanks

2

There are 2 best solutions below

1
On

For Running directly in aws device farm:

Modify your existing karate project according to the below documentation: https://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-appium.html

steps are pretty straightforward, updating pom.xml, creating assembly/zip.xml, and run mvn package to create jar files which you have to zip and upload to devicefarm project.

I noted that running on device farm by directly uploading your project only works with Junit4 hence you can only use karate-junit4 in your dependency

For Local:

Refer DeviceFarmTarget class in https://github.com/ptrthomas/karate-devicefarm-demo and implement a similar one in you existing karate project

public class AwsDeviceFarmMobileTarget implements Target {

    private String arn;
    private String driverType = "android";

    public AwsDeviceFarmMobileTarget(Map<String, Object> options) {
        arn = (String) options.get("arn");
        if (arn == null) {
            throw new RuntimeException("arn is null");
        }
        // update driver type and browserName if needed
    }

    @Override
    public Map<String, Object> start(ScenarioRuntime sr) {
        sr.logger.info("starting driver using: {}", AwsDeviceFarmMobileTarget.class);
        DeviceFarmClient client = DeviceFarmClient.builder().region(Region.US_WEST_2).build();
        CreateTestGridUrlRequest request = CreateTestGridUrlRequest.builder()
                .expiresInSeconds(300)
                .projectArn(arn)
                .build();
        CreateTestGridUrlResponse response = client.createTestGridUrl(request);
        String webDriverUrl = response.url();
        sr.logger.info("aws url provisioned: {}", webDriverUrl);
        Map<String, Object> map = new HashMap();
        map.put("type", driverType);
        map.put("start", false);
        map.put("webDriverUrl", webDriverUrl);
        // this is needed because it can take a minute or two for the "desktop" to be provisioned by aws
        map.put("httpConfig", Collections.singletonMap("readTimeout", 120000));
        // refer: https://docs.aws.amazon.com/devicefarm/latest/testgrid/techref-support.html
        Map<String, Object> session = new HashMap();
        map.put("webDriverSession", session);
        Map<String, Object> capabilities = new HashMap();
        session.put("capabilities", capabilities);
        // for some reason, both are needed for aws device farm
        session.put("desiredCapabilities", capabilities);
        return map;
    }

    @Override
    public Map<String, Object> stop(ScenarioRuntime sr) {
        return Collections.EMPTY_MAP;
    }


}
0
On

Yes, AWS Device Farm does support executing the Karate framework for web testing across Android and iOS devices. The major difference between desktop and mobile testing on AWS Device Farm is that, for mobile testing, we require that tests be packaged and uploaded to our service for server-side execution. For example, in the following code, we use a simple conditional branch to check "are we running server-side for mobile devices or client-side for desktop browser devices":

class DeviceFarmWebTests(unittest.TestCase):

    def setUp(self):
        if os.getenv("DEVICEFARM_DEVICE_NAME"):
            print("Running my test on a real physical device in Device Farm (server-side)")
            url = "http://127.0.0.1:4723/wd/hub"
            desired_capabilities = {}

        else:
            print("Running my test on a desktop browser in Device Farm (client-side)")
            session = boto3.Session(profile_name='simsjon')
            devicefarm = session.client('devicefarm', region_name='us-west-2')
            project_arn = create_project(devicefarm, "Test Desktop Browsers Project") 
            print("Project ARN:", project_arn)
            url = create_presigned_url(devicefarm, arn=project_arn) 
            print("Creating a new remote web driver session at:", url)
            desired_capabilities = DesiredCapabilities.CHROME

        self.driver = webdriver.Remote(command_executor=url,
            desired_capabilities=desired_capabilities) 
        print("A new WebDriver session has been created. SessionId:", self.driver.session_id)

    def test_main(self):
        ...

Please see our instructions here for packaging and uploading tests like this, which will communicate with AWS Device Farm mobile devices through an Appium server (and thus are referred to as Appium tests): https://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-appium.html