Search code examples
typescriptappiumtypescript-typingswebdriver-iotsconfig

How to set up an Appium-Webdriver.io-project to compile typescript-files? [ ERROR @wdio/cli:launcher: No specs found to run, exiting with failure ]


I want to convert my Appium-Javascript boilerplate into a typescript project. I prefer the typed-configuration, as this is officially recommended, and followed the steps provided at the documentation

This is the project's structure:

The project's structure

This is the ‘package.json’-file:

{
  "author": "",
  "dependencies": {
    "@wdio/cli": "^6.5.2",
    "webdriverio": "^6.5.2",
    "ts-node": "^8.10.2",
    "typescript": "^3.9.5"
  },
  "devDependencies": {
    "@types/chai": "^4.2.12",
    "@types/mocha": "^8.0.3",
    "@types/node": "^14.11.2",
    "@types/selenium-webdriver": "^4.0.9",
    "@types/webdriverio": "^5.0.0",
    "@wdio/appium-service": "^6.4.7",
    "@wdio/cucumber-framework": "^6.5.0",
    "@wdio/local-runner": "^6.5.2",
    "@wdio/mocha-framework": "^6.5.0",
    "@wdio/selenium-standalone-service": "^6.4.7",
    "@wdio/spec-reporter": "^6.4.7",
    "@wdio/sync": "^6.5.0",
    "chai": "^4.2.0",
    "npm": "^6.14.8"
  },
  "license": "ISC",
  "main": "wdio.conf.js",
  "name": "android_e2e_appium",
  "scripts": {
    "wdio": "./node_modules/.bin/wdio",
    "pretest": "tsc",
    "test": "wdio ./build/wdio.conf.js"
  },
  "version": "1.0.0"
}

This is the ‘tsconfig.json’-file ('sync-mode'-configuration):

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "sourceMap": false,
    "outDir": "./build",
    "rootDir": "./src",
    "removeComments": true,
    "strict": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "strictPropertyInitialization": true,
    "strictNullChecks": true,
    //"typeRoots": [ "./node_modules/@types" ],
    "types": [
      "node",
      "@wdio/sync",
      //"webdriverio",
      "@wdio/mocha-framework",
      "chai"
    ],
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "inlineSourceMap": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": [
    "./src/**/*.ts"
  ],
  "exclude": [
    "./node_modules",
    "plugins.ts"
  ]
}

This is the ‘wdio.conf.ts’-file:

let {join} = require( 'path' );
exports.config = {
    runner: 'local',
    port: 4723,
    path: '/wd/hub',
    sync: true,
    specs: [
        './src/tests/**/*.js'
    ],
    exclude: [],
    maxInstances: 1,
    capabilities: [{
        'appium:platformName': 'Android',
        'appium:platformVersion': '8.1',
        'appium:deviceName': 'Nexus 6P',
        'appium:automationName': 'UiAutomator2',
        'appium:app': join( process.cwd(), './apk/ApiDemos-debug.apk' ),
        'appium:autoGrantPermissions': true,
        'appium:clearDeviceLogsOnStart': true,
        'appium:newCommandTimeout': 300000
    }],
    logLevel: 'error',
    bail: 0,
    waitforTimeout: 28000,
    connectionRetryTimeout: 90000,
    connectionRetryCount: 3,
    framework: 'mocha',
    reporters: ['spec'],
    mochaOpts: {
        //ui: 'bdd',
        timeout: 60000,
        //compilers:'tsconfig-paths/register'
        //compilers: ['ts:ts-node/register'],
        //requires: ['./test/helpers/common.js']
        require: ['ts-node/register']
    }
};

The file ‘sample.steps.ts’ contains a first test to proove the project's functionality:

import {expect} from 'chai';

describe('Sample test', () => {

    it("should verify that the text entry dialog username & password fields are editable", () => {
        let appBtn: any = $("~App");
        let alertDialogBtn: any = $('//android.widget.TextView[@content-desc="Alert Dialogs"]');
        let textEntryDialogBtn: any = $('//android.widget.Button[@content-desc="Text Entry dialog"]');
        let userNameField: any = $(
            '//android.widget.EditText[@resource-id="io.appium.android.apis:id/username_edit"]');
        let passwordField: any = $(
            '//android.widget.EditText[@resource-id="io.appium.android.apis:id/password_edit"]');

        appBtn.click();
        alertDialogBtn.click();
        textEntryDialogBtn.click();

        let testuser: string = "Test User";
        userNameField.addValue(testuser);
        passwordField.addValue("password");
        expect(userNameField.getText()).equal(testuser);
    });
});

I can compile the typescript from the ‘./src’ into the ‘./build’-folder (as configured) using the command ‘tsc’ without any errors. However, when I run the test, I get the error-message:

ERROR @wdio/cli:launcher: No specs found to run, exiting with failure

I’m pretty sure that the error is in the ‘tsconfig.json’-file, but I can’t put my finger on it. At this point, even the non-typed implementation would do; - I'm unable to implement either.

I pushed the project to github: appium-webdriverIO-typescript


Solution

  • This source provided the solution.

    I was finally able to solve this problem by running the script with the flag --ignoreDeviceController

    Furthermore, I turned the file ‘wdio.conf’ into a javascript-file and moved it back to the project’s root-level. So the following line in the file ‘package.json’ had to be changed accordingly:

    "test": "wdio ./wdio.conf.js --ignoreDeviceController"
    

    If you are still struggling with this issue, consider adding these additional flags:

    --runType=realme

    --relaxedSecurity