Skip to content

Commit

Permalink
Fixed #2573 - fix callback results in section commands
Browse files Browse the repository at this point in the history
  • Loading branch information
lloiser authored and beatfactor committed Mar 23, 2021
1 parent 963a6f7 commit edd0c77
Show file tree
Hide file tree
Showing 18 changed files with 155 additions and 64 deletions.
2 changes: 1 addition & 1 deletion lib/api/expect/assertions/element/_element-assertion.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ExpectElement extends BaseAssertion {
if (Utils.isObject(value) && value.elementId) {
this.elementId = value.elementId;
} else {
this.elementId = value;
this.elementId = this.transport.getElementId(value);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/api/expect/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class ExpectElement extends BaseExpect {
}

if (elementResult && elementResult.value) {
this.elementId = elementResult.value;
this.elementId = this.transport.getElementId(elementResult.value);
if (elementResult.sessionId) {
this.sessionId = elementResult.sessionId;
}
Expand Down
38 changes: 28 additions & 10 deletions lib/api/protocol/_base-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ module.exports = class ProtocolAction {
}
}

static get elementCommandToActionMap() {
return {
element: {
transportAction: 'locateSingleElement',
returnSingleElement: true
},
elements: {
transportAction: 'locateMultipleElements',
returnSingleElement: false
},
elementIdElement: {
transportAction: 'locateSingleElementByElementId',
returnSingleElement: true
},
elementIdElements: {
transportAction: 'locateMultipleElementsByElementId',
returnSingleElement: false
},
};
}

reportProtocolErrors(result) {
return true;
}
Expand All @@ -31,6 +52,10 @@ module.exports = class ProtocolAction {
return this.client.elementLocator;
}

get transport() {
return this.client.transport;
}

/**
* @type {Nightwatch}
* @return {*}
Expand Down Expand Up @@ -85,17 +110,10 @@ module.exports = class ProtocolAction {
* @param {string} protocolCommand either "elements"(multiple) or "element"(single)
*/
async locate({id, element, parentElement, commandName}) {
const commandToActionMap = {
element: 'locateSingleElement',
elements: 'locateMultipleElements',
elementIdElement: 'locateSingleElementByElementId',
elementIdElements: 'locateMultipleElementsByElementId',
};

const transportAction = commandToActionMap[commandName];
const {transportAction, returnSingleElement} = ProtocolAction.elementCommandToActionMap[commandName];

if (element.usingRecursion) {
return this.elementLocator.findElement({element, transportAction});
return this.elementLocator.findElement({element, transportAction, returnSingleElement});
}

if (parentElement) {
Expand All @@ -108,7 +126,7 @@ module.exports = class ProtocolAction {
};
}

id = elementResponse.value;
id = this.transport.getElementId(elementResponse.value);
}

return this.elementLocator.executeProtocolAction({id, element, transportAction, commandName});
Expand Down
7 changes: 4 additions & 3 deletions lib/element/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class ElementCommand extends EventEmitter {
*/
elementFound(response) {
if (response) {
this.elementId = response.value;
this.elementId = this.transport.getElementId(response.value);
}

return this.protocolAction();
Expand Down Expand Up @@ -193,14 +193,15 @@ class ElementCommand extends EventEmitter {
try {
if (WebdriverElementId) {
return {
value: WebdriverElementId,
value: this.transport.toElement(WebdriverElementId),
status: 0,
result: {}
};
}

if (this.element.webElement) {
const webElement = await this.element.convertWebElement();
const webElement = await this.transport.convertWebElement(this.element.webElement);
this.element.elementId = webElement.WebdriverElementId;
this.sessionId = webElement.sessionId;
this.WebdriverElementId = webElement.WebdriverElementId;

Expand Down
16 changes: 0 additions & 16 deletions lib/element/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,22 +166,6 @@ class Element {
return null;
}

async convertWebElement() {
const session = await this.webElement.getDriver().getSession();
const sessionId = session.getId();

this.elementId = await this.webElement.getId();
const WebdriverElementId = this.elementId;

return {
sessionId,
WebdriverElementId,
value: this.elementId,
status: 0,
result: {}
};
}

/**
* Copies selector properties to the first object from the second if the first
* object has undefined or null values for any of those properties.
Expand Down
19 changes: 18 additions & 1 deletion lib/element/locate/elements-by-recursion.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,24 @@ class MultipleElementsByRecursion extends RecursiveLookupBase {
}
});

return this.deferred.promise;
return this.deferred.promise
.then((response) => {
// backward compatibility: keep the "result" on the result object
if (!response.result) {
let {value} = response;
response.result = {
value
};

if (Array.isArray(value) && value.length > 0) {
value = value[0];
}

response.result.WebdriverElementId = this.transport.getElementId(value);
}

return response;
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/element/locate/recursive-lookup.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class RecursiveLookupBase extends EventEmitter {

if (element) {
this.elementLocator.findElement({
id: result.value,
id: this.transport.getElementId(result.value),
element,
transportAction: this.transportAction,
commandName: this.commandName,
Expand Down
21 changes: 9 additions & 12 deletions lib/element/locator.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ class LocateElement {
*/
async findElement({element, commandName, id, transportAction = 'locateMultipleElements', returnSingleElement = true}) {
if (element && element.webElement) {
return element.convertWebElement();
const webElement = await this.transport.convertWebElement(element.webElement);
element.elementId = webElement.WebdriverElementId;

return webElement;
}

if (element && element.sessionId && element.elementId) {
Expand Down Expand Up @@ -106,10 +109,10 @@ class LocateElement {
if (result) {
const elementResult = this.resolveElement(result, element, true);

if (elementResult && !Utils.isUndefined(elementResult.value) && elementResult.value !== null) {
value = elementResult.value;
status = elementResult.status;
result.WebdriverElementId = value;
if (elementResult) {
value = elementResult;
status = 0;
result.WebdriverElementId = this.transport.getElementId(elementResult);
}
}

Expand Down Expand Up @@ -159,13 +162,7 @@ class LocateElement {
value = null;
}

let parsedValue = value && this.transport.getElementId(value);

return {
status: 0,
// for recursive lookups, the value is already parsed
value: Utils.isUndefined(parsedValue) ? value : parsedValue
};
return value;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions lib/transport/jsonwire.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class JsonWireProtocol extends Transport {
getElementId(resultValue) {
return resultValue.ELEMENT;
}
toElement(resultValue) {
return {ELEMENT: resultValue};
}

isResultSuccess(result) {
return result && result.status === Errors.StatusCode.SUCCESS;
Expand Down
4 changes: 4 additions & 0 deletions lib/transport/selenium2.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class Selenium2Protocol extends JsonWire {

return resultValue.ELEMENT;
}

toElement(resultValue) {
return {[Selenium2Protocol.WEB_ELEMENT_ID]: resultValue};
}
}

module.exports = Selenium2Protocol;
28 changes: 28 additions & 0 deletions lib/transport/transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,34 @@ class Transport extends EventEmitter {
return value;
}

/**
* @param {object} value
* @return {object}
*/
toElement(value) {
return value;
}

/**
* Converts a webElement object obtain using selenium-webdriver commands
* @param {WebElement} webElement
*
* @return {Promise<{result: {}, sessionId: *, WebdriverElementId: *, value: *, status: number}>}
*/
async convertWebElement(webElement) {
const elementId = await webElement.getId();
const session = await webElement.getDriver().getSession();
const sessionId = session.getId();

return {
sessionId,
WebdriverElementId: elementId,
value: this.toElement(elementId),
status: 0,
result: {}
};
}

mapWebElementIds(result) {
if (Array.isArray(result.value)) {
result.value = result.value.reduce((prev, item) => {
Expand Down
4 changes: 4 additions & 0 deletions lib/transport/webdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class WebdriverProtocol extends Transport {
return resultValue[Transport.WEB_ELEMENT_ID];
}

toElement(resultValue) {
return {[Transport.WEB_ELEMENT_ID]: resultValue};
}

isResultSuccess(result) {
return result && (typeof result.value != 'undefined') && (!result.status || result.status !== -1);
}
Expand Down
2 changes: 1 addition & 1 deletion test/extra/pageobjects/pages/simplePageObj.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = {
selector: '#signupSection',
commands: {
sectionElements(cb) {
this.api.elements('css selector', '#helpBtn', function(result) {
this.api.elements('css selector', '.btn', function(result) {
cb(result);
});
},
Expand Down
24 changes: 24 additions & 0 deletions test/lib/mocks.json
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,30 @@
"hCode": 604376696
}
},
{
"url": "/wd/hub/session/1352110219202/element/0/elements",
"postdata": {
"using": "css selector",
"value": ".btn"
},
"response": {
"sessionId": "1352110219202",
"status": 0,
"value": [
{
"ELEMENT": "1"
},
{
"ELEMENT": "2"
},
{
"ELEMENT": "3"
}
],
"class": "org.openqa.selenium.remote.Response",
"hCode": 604376696
}
},
{
"url": "/wd/hub/session/1352110219202/buttondown",
"postdata": {
Expand Down
13 changes: 12 additions & 1 deletion test/lib/mocks/mocks-jsonwire.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,18 @@ mocks:
value:
- ELEMENT: '1'

- url: '/wd/hub/session/1352110219202/element/0/elements'
postdata:
using: 'css selector'
value: '.btn'
response:
sessionId: *sessionId
status: 0
value:
- ELEMENT: '1'
- ELEMENT: '2'
- ELEMENT: '3'

- url: '/wd/hub/session/1352110219202/buttondown'
postdata:
button: 0
Expand Down Expand Up @@ -212,4 +224,3 @@ mocks:
- level: 'info'
timestamp: 534547442
message: 'Test log2'

10 changes: 5 additions & 5 deletions test/src/element/testElementCommands.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,9 @@ describe('element base commands', function() {
});

await Nightwatch.api()
.elementIdElements('0', 'css selector', '#helpBtn', function callback(result) {
.elementIdElements('0', 'css selector', '.btn', function callback(result) {
assert.strictEqual(result.status, 0);
assert.deepEqual(result.value, [{ ELEMENT: '1' }]);
assert.deepEqual(result.value, [{ ELEMENT: '1' }, { ELEMENT: '2' }, { ELEMENT: '3' }]);
});

return Nightwatch.start();
Expand All @@ -395,9 +395,9 @@ describe('element base commands', function() {
});

await Nightwatch.api()
.elementIdElements('0', 'css selector', {selector: '#helpBtn', index: 0}, function callback(result) {
.elementIdElements('0', 'css selector', { selector: '.btn', index: 1 }, function callback(result) {
assert.strictEqual(result.status, 0);
assert.deepEqual(result.value, [{ ELEMENT: '1' }]);
assert.deepEqual(result.value, [{ ELEMENT: '2' }]);
});

return Nightwatch.start();
Expand All @@ -410,7 +410,7 @@ describe('element base commands', function() {
});

await Nightwatch.api()
.elementIdElements('0', 'css selector', {selector: '#helpBtn', index: 1}, function callback(result) {
.elementIdElements('0', 'css selector', { selector: '.btn', index: 4 }, function callback(result) {
assert.strictEqual(result.status, -1);
assert.strictEqual(result.value, null);
});
Expand Down
Loading

0 comments on commit edd0c77

Please sign in to comment.