问题
I'm using WebdriverIO and its wdio testrunner with mocha and chai.
I want to build some custom commands, but in this scenario, where and how is the best way to add custom commands?
回答1:
While building a full-fledged automation harness powered by the exact tech-stack you mentioned (WebdriverIO
/Mocha
&Chai
), I have come to the conclusion that Page Objects are't there yet
(it's also a pain to keep them up-to-date) and the best way to harness the complete power of WebdriverIO is to write your own Custom Commands.
The main reasons why I recommend custom commands:
- avoid reusing
waitUntil()
statements (explicitly waiting) for aWebElement
to be displayed; - easily access my
WebElement
modules (files where I mapped myWebElements
based on views, routes, or websites); - reuse the same custom commands in other custom commands;
- the Mocha
it()
(test case) statement is much cleaner and easier to follow.
Here's an example of how you can write a custom click()
(action.js
file):
module.exports = (function() {
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Def: Performs a 'click' action on the given element (WebElement)
* after waiting for the given element to exist and be visible.
* @param: {String} element
* @returns {WebdriverIO.Promise}
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
browser.addCommand('cwClick', function(element) {
var locator = cwElements.<jsonPathTo>[element] ||
thirdPartyElements.<jsonPathTo>[element];
assert.isOk(locator, "\nNo CSS-path for targeted element ('" + element + "')\n");
return browser
.waitUntil(function() {
return browser.isExisting(locator);
}, timeout, "Oups! An error occured.\nReason: element ('" + locator + "') does not exist")
.waitUntil(function() {
return browser.isVisible(locator);
}, timeout, "Oups! An error occured.\nReason: element ('" + locator + "') is not visible")
.waitUntil(function() {
return browser.click(locator);
}, timeout, "Oups! An error occured.\nReason: element ('" + locator + "') could not be clicked")
});
})();
Finally, in your test suite (feature file), import the file that contains your custom command, in this case, action.js
: var action = require('.<pathToCommandsFolder>/action.js');
.
That's it. You're done! :)
Note: In order to keep my custom-cummand files clean, I've broken them down into several categories:
- Actions (
action.js
):- Contains actions such as:
cwClick
,cwGetText
,cwGetValue
,cwSetValue
, etc.
- Contains actions such as:
- Validation (
validate.js
):- Contains validations such as:
isDisplayed
,isNotDisplayed
, etc.
- Contains validations such as:
- Navigation (
navigate.js
):- Contains navigation commands:
cwBack
,cwRefresh
,cwForward
, tab-manipulation-custom-commands, etc.
- Contains navigation commands:
- etc. (the skyhardware is the limit!)
Hope this helps. Cheers!
回答2:
The best place to keep the custom command is in your wdio config file.
before: function(capabilities, specs) {
// Comment why this command is getting added and what it is supposed to do
browser.addCommand('nameOfCommand', function() {
// your code for the command
});
},
When you are finished with adding the custom command in config file. You can call them anywhere in your whole framework by just calling browser object. Like for above custom command to be called : browser.nameOfCommand()
will do the magic.
回答3:
For the record, this is an example of how I'm creating my custom commands inside Page Objects.
var HomePage = function() {
var me = this;
this.clickFlag = function() {
var flag = me.navbar.$('.//li[@class="xtt-popover-click xtt-flags"]'),
flagActive = me.navbar.$('.//li[@class="xtt-popover-click xtt-flags active"]');
flag.click();
flagActive.waitForExist(1000);
}
this.elementThatContainsText = function(tag, text) {
var el;
if (tag) {
el = $('//' + tag + '[contains(content(), "' + text + '")]');
} else {
el = $('//*[contains(content(), "' + text + '")]');
}
return el;
}
this.highlight = function(webElement) {
var id = webElement.getAttribute('id');
if (id) {
browser.execute(function(id) {
$(id).css("background-color", "yellow");
}, id);
}
}
};
Object.defineProperties(HomePage.prototype, {
navbar: {
get: function() {
return $('//div[@class="navbar-right"]');
}
},
comboLanguage: {
get: function() {
return this.navbar.$('.//a[@id="xtt-lang-selector"]');
}
},
ptLink: {
get: function() {
return this.navbar.$('.//a[@href="/institutional/BR/pt/"]');
}
}
});
module.exports = new HomePage();
So, my HomePage have a now a custom clickFlag
command, and a highlight
command. And properties like navbar
and comboLanguage
which are selectors.
来源:https://stackoverflow.com/questions/45481413/where-do-i-add-custom-commands-in-webdriverio-with-wdio-testrunner