Skip to content

Commit

Permalink
Add element property (nightwatchjs#2189)
Browse files Browse the repository at this point in the history
Added W3C Webdriver related element property commands - "getElementProperty" and "elementIdProperty" protocol action.
  • Loading branch information
RafalSkorka authored and beatfactor committed Oct 11, 2019
1 parent 3bfe5a2 commit fd4aff1
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 0 deletions.
35 changes: 35 additions & 0 deletions lib/api/element-commands/getElementProperty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const BaseElementCommand = require('./_baseElementCommand.js');

/**
* Retrieve the value of a property for a given DOM element. Uses `elementIdProperty` protocol command.
*
* @example
* this.demoTest = function (browser) {
* browser.getElementProperty("#main ul li a.first", "href", function(result) {
* this.assert.equal(typeof result, "object");
* this.assert.equal(result.status, 0);
* this.assert.equal(result.value, 'https://nightwatchjs.org/');
* });
* };
*
*
* @method getElementProperty
* @syntax .getElementProperty(selector, property, callback)
* @param {string} selector The CSS/Xpath selector used to locate the element.
* @param {string} property The property to inspect.
* @param {function} callback Callback function which is called with the result value.
* @see elementIdProperty
* @returns {*} The value of the property
* @api protocol.elementstate
*/
class GetElementProperty extends BaseElementCommand {
get extraArgsCount() {
return 1;
}

get elementProtocolAction() {
return 'getElementProperty';
}
}

module.exports = GetElementProperty;
18 changes: 18 additions & 0 deletions lib/api/protocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,24 @@ module.exports = class ProtocolActions {
return this.TransportActions.getElementCSSValue(webElementId, cssPropertyName, callback);
},

/**
* Retrieve the computed value of the given property of the given element.
*
* The property to query should be specified using the CSS property name, not the JavaScript property name (e.g. background-color instead of backgroundColor).
*
* @link /#get-element-property
* @param {string} webElementId The [Web Element ID](https://www.w3.org/TR/webdriver1/#dfn-web-elements) of the element to route the command to.
* @param {string} propertyName
* @param {function} callback Callback function which is called with the result value.
* @api protocol.elementinternal
* @internal
*/
elementIdProperty(webElementId, propertyName, callback) {
ProtocolActions.validateElementId(webElementId, 'elementIdProperty');

return this.TransportActions.getElementProperty(webElementId, propertyName, callback);
},

/**
* Scrolls into view a submittable element excluding buttons or editable element, and then attempts to clear its value, reset the checked state, or text content.
*
Expand Down
4 changes: 4 additions & 0 deletions lib/transport/jsonwire/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ module.exports = {
return `/element/${id}/css/${cssPropertyName}`;
},

getElementProperty(id, propertyName) {
return `/element/${id}/property/${propertyName}`;
},

getElementTagName(id) {
return `/element/${id}/name`;
},
Expand Down
18 changes: 18 additions & 0 deletions test/lib/nocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,24 @@ module.exports = {
return this;
},

property(value, times) {
var mock = nock('http://localhost:10195')
.get('/wd/hub/session/1352110219202/element/0/property/display');

if (times) {
mock.times(times);
}

mock.reply(200, {
status: 0,
sessionId: '1352110219202',
value: value,
state: 'success'
});

return this;
},

enabled(times) {
var mock = nock('http://localhost:10195')
.get('/wd/hub/session/1352110219202/element/0/enabled');
Expand Down
32 changes: 32 additions & 0 deletions test/src/api/commands/testGetElementProperty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const assert = require('assert');
const MockServer = require('../../../lib/mockserver.js');
const CommandGlobals = require('../../../lib/globals/commands.js');

describe('getElementProperty', function() {
before(function(done) {
CommandGlobals.beforeEach.call(this, done);
});

after(function(done) {
CommandGlobals.afterEach.call(this, done);
});

it('client.getElementProperty()', function(done) {
MockServer.addMock({
url : '/wd/hub/session/1352110219202/element/0/property/display',
method:'GET',
response : JSON.stringify({
sessionId: '1352110219202',
status:0,
value : 'block'
})
});

this.client.api.getElementProperty('#weblogin', 'display', function callback(result) {
assert.strictEqual(result.value, 'block');
});

this.client.start(done);
});

});
22 changes: 22 additions & 0 deletions test/src/api/protocol/testElementCommands.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,28 @@ describe('element actions', function () {
}).then(result => assert.strictEqual(result, true));
});

it('testElementIdProperty', function () {
return Globals.protocolTest.call(this, {
assertion: function (opts) {
assert.equal(opts.method, 'GET');
assert.equal(opts.path, '/session/1352110219202/element/TEST_ELEMENT/property/test_property');
},
commandName: 'elementIdProperty',
args: ['TEST_ELEMENT', 'test_property']
});
});

it('testElementIdProperty invalid element ID', function () {
return Globals.protocolTest.call(this, {
commandName: 'elementIdProperty',
args: [false, 'test_property']
}).catch(err => {
assert.equal(err.message, 'First argument passed to .elementIdProperty() should be a web element ID string. Received boolean.');

return true;
}).then(result => assert.strictEqual(result, true));
});

it('testElementIdDisplayed', function () {
return Globals.protocolTest.call(this, {
assertion: function (opts) {
Expand Down

0 comments on commit fd4aff1

Please sign in to comment.