Search code examples
javascriptwebdriver-io

how to write custom commands in webdriverio


I am trying to write a custom command like this

 module.exports = (function() {
    browser.addCommand('selectABC', (element) => {
    let elem = element
    ...

   });
 })

And in conf.ts, I have added this

import * as custom from '../services/customCommands.service';

exports.config = {

/**
 * Gets executed before test execution begins. At this point you can access to all global
 * variables like `browser`. It is the perfect place to define custom commands.
 * @param {Array.<Object>} capabilities list of capabilities details
 * @param {Array.<String>} specs List of spec file paths that are to be run
 */
before: function (capabilities, specs) {
  // Add commands to WebdriverIO
  Object.keys(commands).forEach(key => {
    browser.addCommand(key, commands[key]);
  })
},

But when I try in the code like this

  class NewPage {
     public createnew(data) {
         browser.selectABC($('abc'))
     }
  }

or

 class NewPage {
     public createnew(data) {
         $('abc').selectABC()
     }
  }

This does not work and throws this error

error TS2339: Property 'selectABC' does not exist on type 'Client'.

What am i missing? Thanks!


Solution

  • wdio.conf.js

    const commands = require('./commands.js')
    
    exports.config = {
      before: function (capabilities, specs) {
        // Add commands to WebdriverIO
        Object.keys(commands).forEach(key => {
          browser.addCommand(key, commands[key]);
        })
      }
    }
    

    commands.js

    module.exports = {
        getUrlAndTitle: function () {
            return {
                url: this.getUrl(),
                title: this.getTitle()
            };
        },
        otherCommand: function () {}
    }
    

    test.js

    const chai = require('chai');
    const assert = require("assert");
    const expect = require('chai').expect;
    const chaiWebdriver = require('chai-webdriverio').default;
    chai.use(chaiWebdriver(browser));
    
    describe("custom commands", () => {
      it("should have custom commands", () => {
        const getUrlAndTitle = browser.getUrlAndTitle();
        const title = getUrlAndTitle.title;
        assert.equal(title, "Custom Commands");
    
        // You could do the same equality check with:
        expect(title === "Custom Commands").to.be.true;
    
        // Or also check equality with: 
        expect(title).to.equal("Custom Commands");
      });
    });
    
    

    If you'd also like to use ES6 style javascript in your tests you can do the following:

    npm i @babel/cli @babel/core @babel/preset-env @babel/register --save
    

    In your package.json:

    {
      "name": "babelify-webdriverIO-mocha-chai",
      "version": "2.0.0",
      "description": "babelify-webdriverIO-mocha-chai",
      "scripts": {
        "test": "node node_modules/.bin/wdio ./config/wdio.dev.conf.js"
      },
      "author": "Zero Cool",
      "dependencies": {
        "@babel/cli": "^7.2.3",
        "@babel/core": "^7.2.2",
        "@babel/preset-env": "^7.2.3",
        "@babel/register": "^7.0.0",
        "@wdio/sauce-service": "^5.3.2",
        "@wdio/selenium-standalone-service": "^5.2.2",
        "@wdio/spec-reporter": "^5.2.3",
        "@wdio/sync": "^5.3.2",
        "chai": "^4.2.0",
        "webdriverio": "^5.3.5"
      },
      "devDependencies": {
        "@wdio/cli": "^5.3.5",
        "@wdio/local-runner": "^5.3.5",
        "@wdio/mocha-framework": "^5.3.2",
        "chai-webdriverio": "^1.0.0",
        "selenium-standalone": "^6.15.4"
      },
      "babel": {
        "presets": [
          [
            "@babel/preset-env",
            {
              "targets": {
                "node": "current"
              }
            }
          ]
        ]
      }
    }
    

    Your test file could now look like this:

    import chai from "chai";
    import { assert, expect } from "chai";
    import chaiWebdriver from "chai-webdriverio";
    chai.use(chaiWebdriver(browser));
    
    describe("custom commands", () => {
      it("should have custom commands", () => {
        const getUrlAndTitle = browser.getUrlAndTitle();
        const title = getUrlAndTitle.title;
        assert.equal(title, "Custom Commands");
    
        // You could do the same equality check with:
        expect(title === "Custom Commands").to.be.true;
    
        // Or also check equality with: 
        expect(title).to.equal("Custom Commands");
      });
    });
    

    If you are using mocha be sure to include this in your wdio.conf.js:

        mochaOpts: {
          ui: "bdd",
          timeout: 10000,
          compilers: ["js:@babel/register"]
        }