-
Notifications
You must be signed in to change notification settings - Fork 998
Labels
bugSomething isn't workingSomething isn't workinggood first issueGood for newcomersGood for newcomerspriority:p2Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrectBugs and spec inconsistencies which cause telemetry to be incomplete or incorrecttriageup-for-grabsGood for taking. Extra help will be provided by maintainersGood for taking. Extra help will be provided by maintainers
Description
What happened?
getElementXPath returns incorrect values.
Steps to Reproduce
Run this code in about:blank. Functions are copied from @opentelemetry/sdk-trace-web@1.30.1.
document.documentElement.innerHTML = `<body id="body-id"><div></div></body>`
console.log('Body XPath:', getElementXPath(document.body, true))
console.log('Div XPath:', getElementXPath(document.querySelector('div'), true))
function getElementXPath(target, optimised) {
if (target.nodeType === Node.DOCUMENT_NODE) {
return '/';
}
const targetValue = getNodeValue(target, optimised);
if (optimised && targetValue.indexOf('@id') > 0) {
return targetValue;
}
let xpath = '';
if (target.parentNode) {
xpath += getElementXPath(target.parentNode, false);
}
xpath += targetValue;
return xpath;
}
function getNodeValue(target, optimised) {
const nodeType = target.nodeType;
const index = getNodeIndex(target);
let nodeValue = '';
if (nodeType === Node.ELEMENT_NODE) {
const id = target.getAttribute('id');
if (optimised && id) {
return `//*[@id="${id}"]`;
}
nodeValue = target.localName;
}
else if (nodeType === Node.TEXT_NODE ||
nodeType === Node.CDATA_SECTION_NODE) {
nodeValue = 'text()';
}
else if (nodeType === Node.COMMENT_NODE) {
nodeValue = 'comment()';
}
else {
return '';
}
// if index is 1 it can be omitted in xpath
if (nodeValue && index > 1) {
return `/${nodeValue}[${index}]`;
}
return `/${nodeValue}`;
}
function getNodeIndex(target) {
if (!target.parentNode) {
return 0;
}
const allowedTypes = [target.nodeType];
if (target.nodeType === Node.CDATA_SECTION_NODE) {
allowedTypes.push(Node.TEXT_NODE);
}
let elements = Array.from(target.parentNode.childNodes);
elements = elements.filter((element) => {
const localName = element.localName;
return (allowedTypes.indexOf(element.nodeType) >= 0 &&
localName === target.localName);
});
if (elements.length >= 1) {
return elements.indexOf(target) + 1; // xpath starts from 1
}
// if there are no other similar child xpath doesn't need index
return 0;
}
Expected Result
Body XPath: //*[@id="body-id"]
Div XPath: //*[@id="body-id"]/div
Actual Result
Body XPath: //*[@id="body-id"]
Div XPath: //html/body/div
Additional Details
getElementXPath does not pass parameter optimised recursively.
The line
xpath += getElementXPath(target.parentNode, false);
should be
xpath += getElementXPath(target.parentNode, optimised);
OpenTelemetry Setup Code
package.json
Relevant log output
Operating System and Version
No response
Runtime and Version
No response
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workinggood first issueGood for newcomersGood for newcomerspriority:p2Bugs and spec inconsistencies which cause telemetry to be incomplete or incorrectBugs and spec inconsistencies which cause telemetry to be incomplete or incorrecttriageup-for-grabsGood for taking. Extra help will be provided by maintainersGood for taking. Extra help will be provided by maintainers