Skip to content

Commit

Permalink
Add selector and error line for "staleElementReferenceError" (#4214)
Browse files Browse the repository at this point in the history
Fixes #4184
  • Loading branch information
pujagani authored Sep 17, 2024
1 parent cf0d45a commit 23df1db
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 36 deletions.
16 changes: 16 additions & 0 deletions examples/tests/staleElementReferenceError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
describe('stale element reference error', function() {

it('should add selector and error line for stale element reference error', function() {
const deletedElement = element(by.id('deleted'));
const deleteElement = element(by.id('delete'));
browser
.navigateTo('https://www.selenium.dev/selenium/web/javascriptPage.html')
.click(deletedElement);

browser.click(deleteElement);

browser.click(deletedElement);
});

after(browser => browser.end());
});
2 changes: 1 addition & 1 deletion lib/element/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class ElementCommand extends EventEmitter {
elementId = selector;
}

return this.transport.executeProtocolAction({actionName, args: [elementId, ...args], sessionId});
return this.transport.executeProtocolAction({actionName, args: [elementId, ...args, {selector: this.selector, stackTrace: this.stackTrace}], sessionId});
}

async complete(err, response) {
Expand Down
25 changes: 22 additions & 3 deletions lib/transport/selenium-webdriver/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const {error} = require('selenium-webdriver');

const {Logger, isObject, isFunction, isString} = require('../../utils');
const MethodMappings = require('./method-mappings.js');
const {filterStackTrace} = require('../../utils/stackTrace');

class TransportActions {
get transport() {
Expand Down Expand Up @@ -70,7 +71,8 @@ class TransportActions {

return this.makeResult(result);
} catch (err) {
const error = this.handleError(err, name);

const error = this.handleError(err, name, args);

return {
error,
Expand All @@ -96,7 +98,7 @@ class TransportActions {
return result;
}

handleError(err, commandName) {
handleError(err, commandName, args = undefined) {
let errorMsg = 'Unknown error';
try {
this.transport.handleErrorResponse(err);
Expand All @@ -123,7 +125,24 @@ class TransportActions {
const {shouldRegisterError} = this.transport;
const {lastError, retriesCount} = this;
if (shouldRegisterError(err) && (retriesCount < 1 || lastError && err.name !== lastError.name)) {
Logger.error(`Error while running .${commandName}() protocol action: ${errorMsg}\n`);
err.message = `Error while running .${commandName}() protocol action: ${errorMsg}\n`;

if (args && args.length > 0) {
const lastArg = args[args.length - 1];
if (lastArg && typeof lastArg === 'object' && !Array.isArray(lastArg)) {
const {selector = null, stackTrace = null} = lastArg;

if (selector) {
err.message += `Selector: ${selector}\n`;
}

if (stackTrace) {
err.stack = filterStackTrace(stackTrace);
}
}
}

Logger.error(err);
this.lastError = err;
}
if (this.lastError && err.name === this.lastError.name) {
Expand Down
23 changes: 12 additions & 11 deletions test/src/api/commands/element/testClickAndHold.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ describe('.clickAndHold()', function() {

return Promise.resolve({
status: 0,
value:null
value: null
});
}
};

this.client.api.clickAndHold('#weblogin', function callback(result) {
assert.deepStrictEqual(clickAndHoldArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b'])
assert.ok(clickAndHoldArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, 0);
assert.strictEqual(this, api);
});
Expand All @@ -39,16 +39,16 @@ describe('.clickAndHold()', function() {
clickAndHoldArgs = args;

return Promise.resolve({
status:0,
status: 0,
value: null
})
}
});
};

this.client.api.useXpath()
.clickAndHold('//weblogin', function callback(result) {
assert.deepStrictEqual(clickAndHoldArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b'])
assert.ok(clickAndHoldArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, 0);
})
});


this.client.start(done);
Expand All @@ -60,21 +60,22 @@ describe('.clickAndHold()', function() {
let clickAndHoldArgs;
this.client.transport.Actions.session.pressAndHold = function(args) {
clickAndHoldArgs = args;

return Promise.resolve({
status: -1,
value: null,
error: new Error('Element could not be scrolled into view')
});
}
};

this.client.api.clickAndHold({
retryInterval: 50,
timeout: 100,
selector: '#weblogin'
}, function(result) {
assert.deepStrictEqual(clickAndHoldArgs.args,['5cc459b8-36a8-3042-8b4a-258883ea642b'])
assert.ok(clickAndHoldArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, -1);
assert.strictEqual(result.value.error,'An error occurred while running .clickAndHold() command on <#weblogin>: Element could not be scrolled into view')
assert.strictEqual(result.value.error, 'An error occurred while running .clickAndHold() command on <#weblogin>: Element could not be scrolled into view');
});

this.client.start(done);
Expand Down
6 changes: 3 additions & 3 deletions test/src/api/commands/element/testDoubleClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('.doubleClick()', function() {

this.client.api.doubleClick('#weblogin', function callback(result) {
assert.strictEqual(result.status, 0);
assert.deepStrictEqual(doubleClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b']);
assert.ok(doubleClickArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(this, api);
});

Expand All @@ -46,7 +46,7 @@ describe('.doubleClick()', function() {

this.client.api.useXpath()
.doubleClick('//weblogin', function callback(result) {
assert.deepStrictEqual(doubleClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b']);
assert.ok(doubleClickArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, 0);
});
this.client.start(done);
Expand All @@ -70,7 +70,7 @@ describe('.doubleClick()', function() {
timeout: 100,
selector: '#weblogin'
}, function(result) {
assert.deepStrictEqual(doubleClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b']);
assert.ok(doubleClickArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, -1);
assert.strictEqual(result.value.error, 'An error occurred while running .doubleClick() command on <#weblogin>: Element could not be scrolled into view');
});
Expand Down
6 changes: 4 additions & 2 deletions test/src/api/commands/element/testDragAndDrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ describe('moveToElement', function() {
};

this.client.api.dragAndDrop('css selector', '#weblogin', {x: 10, y: 10}, function(result) {
assert.deepStrictEqual(dragArgs, ['0', {x: 10, y: 10}]);
assert.deepEqual(dragArgs[0], '0');
assert.deepEqual(dragArgs[1], {x: 10, y: 10});
assert.strictEqual(result.status, 0);
});

Expand All @@ -39,7 +40,8 @@ describe('moveToElement', function() {
};

this.client.api.dragAndDrop('css selector', '#weblogin', '0', function(result) {
assert.deepStrictEqual(dragArgs, ['0', '0']);
assert.deepEqual(dragArgs[0], '0');
assert.deepEqual(dragArgs[1], '0');
assert.strictEqual(result.status, 0);
});

Expand Down
16 changes: 12 additions & 4 deletions test/src/api/commands/element/testMoveToElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,24 @@ describe('moveToElement', function() {
};

this.client.api.moveToElement('css selector', '#weblogin', null, null, function(result) {
assert.deepStrictEqual(moveToArgs, ['0', null, null]);
assert.deepStrictEqual(moveToArgs[0], '0');
assert.deepStrictEqual(moveToArgs[1], null);
assert.deepStrictEqual(moveToArgs[2], null);
assert.strictEqual(result.status, 0);
}).moveToElement('#weblogin', null, null, function(result) {
assert.deepStrictEqual(moveToArgs, ['0', null, null]);
assert.deepStrictEqual(moveToArgs[0], '0');
assert.deepStrictEqual(moveToArgs[1], null);
assert.deepStrictEqual(moveToArgs[2], null);
assert.strictEqual(result.status, 0);
}).moveTo('0', null, null, function(result) {
assert.deepStrictEqual(moveToArgs, ['0', 0, 0]);
assert.deepStrictEqual(moveToArgs[0], '0');
assert.deepStrictEqual(moveToArgs[1], 0);
assert.deepStrictEqual(moveToArgs[2], 0);
assert.strictEqual(result.status, 0);
}).moveToElement('#weblogin', 1, 1, function(result) {
assert.deepStrictEqual(moveToArgs, ['0', 1, 1]);
assert.deepStrictEqual(moveToArgs[0], '0');
assert.deepStrictEqual(moveToArgs[1], 1);
assert.deepStrictEqual(moveToArgs[2], 1);
assert.strictEqual(result.status, 0);
});

Expand Down
25 changes: 13 additions & 12 deletions test/src/api/commands/element/testRightClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ describe('.rightClick()', function() {
rightClickArgs = args;

return Promise.resolve({
status:0,
status: 0,
value: null
})
}
});
};

this.client.api.rightClick('#weblogin', function callback(result) {
assert.deepStrictEqual(rightClickArgs.args,['5cc459b8-36a8-3042-8b4a-258883ea642b'])
assert.ok(rightClickArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, 0);
assert.strictEqual(this, api);
});
Expand All @@ -39,16 +39,16 @@ describe('.rightClick()', function() {
rightClickArgs = args;

return Promise.resolve({
status:0,
status: 0,
value: null
})
}
});
};

this.client.api.useXpath()
.rightClick('//weblogin', function callback(result) {
assert.deepStrictEqual(rightClickArgs.args, ['5cc459b8-36a8-3042-8b4a-258883ea642b'])
assert.ok(rightClickArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, 0);
})
});

this.client.start(done);
});
Expand All @@ -57,21 +57,22 @@ describe('.rightClick()', function() {
let rightClickArgs;
this.client.transport.Actions.session.contextClick = function(args) {
rightClickArgs = args;

return Promise.resolve({
status: -1,
value: null,
error: new Error('Element could not be scrolled into view')
});
}
};

this.client.api.rightClick({
retryInterval: 50,
timeout: 100,
selector: '#weblogin'
}, function(result) {
assert.deepStrictEqual(rightClickArgs.args,['5cc459b8-36a8-3042-8b4a-258883ea642b'])
assert.ok(rightClickArgs.args.includes('5cc459b8-36a8-3042-8b4a-258883ea642b'));
assert.strictEqual(result.status, -1);
assert.strictEqual(result.value.error,'An error occurred while running .rightClick() command on <#weblogin>: Element could not be scrolled into view')
assert.strictEqual(result.value.error, 'An error occurred while running .rightClick() command on <#weblogin>: Element could not be scrolled into view');
});

this.client.start(done);
Expand Down

0 comments on commit 23df1db

Please sign in to comment.