Commit 7d9968e7 authored by Ian Struiksma's avatar Ian Struiksma Committed by Commit Bot

Clean up temporary logging iframe in automation_helper

For some sites they overload console commands, so we
create an iframe to log element info for debugging.

We need to make sure to remove that iframe afterwards, or
we build up a collection of them that might affect elements
on the page, particularly on lower resolutions.

Bug: 984664
Change-Id: I2f81cd8e563c4ca275f561efe94bb03027ee0d8f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1884815
Auto-Submit: Ian Struiksma <ianstruiksma@google.com>
Commit-Queue: Caleb Rouleau <crouleau@chromium.org>
Reviewed-by: default avatarCaleb Rouleau <crouleau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711370}
parent aa7cd162
...@@ -25,63 +25,67 @@ const automation_helper = (function() { ...@@ -25,63 +25,67 @@ const automation_helper = (function() {
this.DomElementReadyState.visible | this.DomElementReadyState.visible |
this.DomElementReadyState.enabled | this.DomElementReadyState.enabled |
this.DomElementReadyState.on_top) { this.DomElementReadyState.on_top) {
let isReady = true;
// Some sites override the console function locally, // Some sites override the console function locally,
// this ensures our function can write to log // this ensures our function can write to log
var frame = document.createElement('iframe'); var frame = document.createElement('iframe');
document.body.appendChild(frame); try {
console = frame.contentWindow.console; document.body.appendChild(frame);
console = frame.contentWindow.console;
const element = getElementFunction(); const element = getElementFunction();
let isReady = true; let logDataArr = [];
let logDataArr = []; logDataArr.push('[Element (' + xpath + ')]');
logDataArr.push('[Element (' + xpath + ')]'); if (element) {
if (element) { logDataArr.push('[FOUND]');
logDataArr.push('[FOUND]'); let target = element;
let target = element; if (state_flags & this.DomElementReadyState.visible) {
if (state_flags & this.DomElementReadyState.visible) { // In some custom select drop downs, like the ones on Amazon.com and
// In some custom select drop downs, like the ones on Amazon.com and // Zappos.com, the drop down options are hosted inside a span element
// Zappos.com, the drop down options are hosted inside a span element // that is the immediate sibling, rather than the descendant, of the
// that is the immediate sibling, rather than the descendant, of the // select dropdown.
// select dropdown. // In these cases, check if the span is visible instead.
// In these cases, check if the span is visible instead. if (element.offsetParent === null &&
if (element.offsetParent === null && element instanceof HTMLSelectElement &&
element instanceof HTMLSelectElement && element.nextElementSibling instanceof HTMLSpanElement) {
element.nextElementSibling instanceof HTMLSpanElement) { logDataArr.push("[Moved to nextElementSibling]");
logDataArr.push("[Moved to nextElementSibling]"); target = element.nextElementSibling;
target = element.nextElementSibling; }
const isVisible = (target.offsetParent !== null) &&
(target.offsetWidth > 0) && (target.offsetHeight > 0);
logDataArr.push('[isVisible:' + isVisible + ']');
isReady = isReady && isVisible;
} }
const isVisible = (target.offsetParent !== null) && if (state_flags & this.DomElementReadyState.on_top) {
(target.offsetWidth > 0) && (target.offsetHeight > 0); // The document.elementFromPoint function only acts on an element
logDataArr.push('[isVisible:' + isVisible + ']'); // inside the viewport. Actively scroll the element into view first.
isReady = isReady && isVisible; element.scrollIntoView({block:"center", inline:"center"});
} const rect = target.getBoundingClientRect();
if (state_flags & this.DomElementReadyState.on_top) { // Check that the element is not concealed behind another element.
// The document.elementFromPoint function only acts on an element const topElement = document.elementFromPoint(
// inside the viewport. Actively scroll the element into view first. // As coordinates, use the center of the element, minus the
element.scrollIntoView({block:"center", inline:"center"}); // window offset in case the element is outside the view.
const rect = target.getBoundingClientRect(); rect.left + rect.width / 2, rect.top + rect.height / 2);
// Check that the element is not concealed behind another element. const isTop = target.contains(topElement) ||
const topElement = document.elementFromPoint( target.isSameNode(topElement);
// As coordinates, use the center of the element, minus the isReady = isReady && isTop;
// window offset in case the element is outside the view. logDataArr.push('[OnTop:' + isTop + ':' + topElement.localName + ']');
rect.left + rect.width / 2, rect.top + rect.height / 2); }
const isOnTop = target.contains(topElement) || if (state_flags & this.DomElementReadyState.enabled) {
target.isSameNode(topElement); const isEnabled = !element.disabled;
isReady = isReady && isOnTop; logDataArr.push('[Enabled:' + isEnabled + ']');
logDataArr.push('[OnTop:' + isOnTop + ':' + topElement.localName + ']'); isReady = isReady && isEnabled;
} }
if (state_flags & this.DomElementReadyState.enabled) { } else {
const isEnabled = !element.disabled; isReady = false;
logDataArr.push('[Enabled:' + isEnabled + ']'); logDataArr.push('[NOT FOUND]');
isReady = isReady && isEnabled;
} }
} else { logDataArr.push('[FinalReady:' + isReady + ']');
isReady = false; console.log(logDataArr.join(""));
logDataArr.push('[NOT FOUND]'); } finally {
// Remove our temporary console iframe
frame.remove();
} }
logDataArr.push('[FinalReady:' + isReady + ']');
console.log(logDataArr.join(""));
return isReady; return isReady;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment