cordovaappiumwebdriver-ioaws-device-farm

WebdriverIO "Unable to open 'badging': No such file or directory"


I'm having trouble running E2E tests on AWS DeviceFarm. Have been getting this error when trying to run Appium via webdriverIO:

2025-01-15T14:15:06.904Z WARN webdriver: WebDriverError: An unknown server-side error occurred while processing the command. Original error: Cannot read the manifest from '/tmp/devicefarm-workspace/execution-afszvhzs/uploads-c1qbmila/app-g56kvzrf.apk'. Update build tools to use a newer aapt2 version. Original error: W/ziparchive(19414): Unable to open 'badging': No such file or directory
[0-0] badging: error: No such file or directory.
[0-0]  when running "http://localhost:4723/wd/hub/session" with method "POST" and args "{"capabilities":{"alwaysMatch":{"platformName":"android","appium:webviewConnectTimeout":90000,"appium:deviceName":"Testing Device","appium:automationName":"UiAutomator2","appium:appPackage":"com.my-app.app","appium:appWaitActivity":"MainActivity","appium:appWaitDuration":20000,"appium:newCommandTimeout":360,"appium:sessionOverride":false,"appium:autoGrantPermissions":true,"appium:fullReset":false,"appium:autoWebview":false},"firstMatch":[{}]}}"

The (not so) funny thing is that until yesterday, the same code run successfully. It still does in my local env, but can't still quite figure out what might have changed in AWS to get this error. And worst of all, couldn't find anything while searching for this error.

BTW, tried building the APK in question both locally and on my bitbucket pipeline, and the error is the same.

Any thoughts? I'm quite lost here


Here's the yaml test spec file:

version: 0.1

android_test_host: amazon_linux_2

phases:

  install:
    commands:
      - devicefarm-cli use node 20
      - node --version

      - devicefarm-cli use appium 2
      - npm i -g appium@2.15.0
      - appium driver uninstall uiautomator2
      - appium driver install uiautomator2@3.9.2

      - appium -v

      - export APPIUM_BASE_PATH=/wd/hub

      # Install the NodeJS dependencies.
      - cd $DEVICEFARM_TEST_PACKAGE_PATH
      - npm i

  pre_test:
    commands:

      - |-
        appium --base-path=$APPIUM_BASE_PATH --log $DEVICEFARM_LOG_DIR --log-timestamp \
          --log-no-colors --relaxed-security --default-capabilities \
          "{\"appium:deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \
          \"platformName\": \"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \
          \"appium:app\": \"$DEVICEFARM_APP_PATH\", \
          \"appium:udid\":\"$DEVICEFARM_DEVICE_UDID\", \
          \"appium:platformVersion\": \"$DEVICEFARM_DEVICE_OS_VERSION\", \
          \"appium:chromedriverExecutableDir\": \"$DEVICEFARM_CHROMEDRIVER_EXECUTABLE_DIR\", \
          \"appium:automationName\": \"UiAutomator2\", \
          \"appium:autoGrantPermissions\": true }" \
          >> $DEVICEFARM_LOG_DIR/appiumlog.txt   2>&1 &

      # This code will wait until the Appium server starts.
      - |-
        appium_initialization_time=0;
        until curl --silent --fail "http://0.0.0.0:4723${APPIUM_BASE_PATH}/status"; do
          if [[ $appium_initialization_time -gt 30 ]]; then
            echo "Appium did not start within 30 seconds. Exiting...";
            exit 1;
          fi;
          appium_initialization_time=$((appium_initialization_time + 1));
          echo "Waiting for Appium to start on port 4723...";
          sleep 1;
        done;
        grep -i "Appium REST http interface listener started on 0.0.0.0:4723" $DEVICEFARM_LOG_DIR/appiumlog.txt >> /dev/null 2>&1;

  # The test phase contains commands for running your tests.
  test:
    commands:
      - cd $DEVICEFARM_TEST_PACKAGE_PATH
      - echo "Starting the Appium NodeJS test"
      
      - npm run test

  post_test:
    commands:
      - cp $DEVICEFARM_TEST_PACKAGE_PATH/test-report/* $DEVICEFARM_LOG_DIR/
      - ls -l $DEVICEFARM_LOG_DIR
artifacts:
  - $DEVICEFARM_LOG_DIR

wdio shared config:

import { type Options } from '@wdio/types';
import * as helper from "../helpers/basic-helper";
import {constants} from "../constants/constants";
import axios from "axios";
import moment = require("moment");
import {Auth0Api} from "../apis/auth0Api";
export const config: Options.Testrunner = {
  //
  runner: 'local',

  port: 4723,
  path: '/wd/hub/',
  specs: [
    '../specs/auth.e2e.ts',
    '../specs/tracker.e2e.ts',
    // '../specs/remove.e2e.ts',
  ],
  // Patterns to exclude.
  exclude: [
    // 'path/to/excluded/files'
  ],
  maxInstances: 1,
  logLevel: 'info',

  bail: 1,

  baseUrl: 'http://localhost:8100',
  //
  // Default timeout for all waitFor* commands.
  waitforTimeout: 20000,
  //
  // Default timeout in milliseconds for request
  // if browser driver or grid doesn't send response
  connectionRetryTimeout: 120000,
  //
  // Default request retries count
  connectionRetryCount: 3,

  services: [],

  framework: 'jasmine',

  reporters: [
    'spec',
    ['junit', {
      outputDir: './test-report/',
      outputFileFormat: function(options) { // optional
        return `test-output.xml`
      }
    }],
  ],
  suites: {
    authentication: ['../specs/auth.e2e.ts'],
    tracker: ['../specs/tracker.e2e.ts'],
  },
  // Options to be passed to Jasmine.
  jasmineOpts: {
    // Jasmine default timeout
    defaultTimeoutInterval: 60000,
    stopOnSpecFailure: true,
    stopSpecOnExpectationFailure: true,

    expectationResultHandler: function(passed: any, assertion: any) {
      // do something
    },
  },
  afterTest: async function(test, context, { error, result, duration, passed, retries }) {
    if(!passed) {
      const fileName = `./test-report/${test.fullName}-${moment().unix()}-screenshot.png`;
      const screenshotName = await browser.saveScreenshot(fileName);
    }
  },

};

Solution

  • So, managed to reach AWS support and they came with the solution right away.

    If anyone's hit this same issue, changing these versions did the trick. Seems there's some incompatibility between Appium and uiautomator2 on my setup.

    Here's what needs to be changed:

    - npm i -g appium@2.15.0
    - appium driver install uiautomator2@3.9.2
    

    to

    - npm install -g appium@2.4.1
    - appium driver install uiautomator2@2.44.0
    

    That's it. Hope someone finds it useful :)