webentwicklung-frage-antwort-db.com.de

Wie funktioniert die Methode isDisplayed () von Selenium WebDriver?

Ich habe derzeit eine große Anzahl von Umständen, unter denen ich überprüfen muss, ob eine Seite (mit all ihren Elementen) korrekt angezeigt wird. Die isDisplayed() -Methode von WebElement scheint eine logische Methode dafür zu sein. Ich möchte jedoch genau verstehen, wie diese Methode ermittelt, ob ein Element "angezeigt" wird oder nicht. Das javadoc gibt keinen Aufschluss über die Funktionsweise der Methode, und andere Informationen im Web scheinen bestenfalls spärlich zu sein.

Wenn jemand eine detaillierte Beschreibung der Funktionsweise dieser Methode geben könnte, wäre ich sehr dankbar.

34
Mr. Spice

WebDriver hat eine eigene W3C Spezifikation .

Der Abschnitt über Sichtbarkeit bestimmen ist, was Sie suchen.

Ich würde warnen, dass das Aussprechen von "wird angezeigt" ein so weit gefasster Begriff ist, dass es viele Szenarien gibt. Daher kann es durchaus Situationen geben, die WebDriver nicht berücksichtigt.

Es ist also wichtig wichtig , sich daran zu erinnern, dass etwas, das "angezeigt" oder "sichtbar" ist , viele Bedeutungen hat . (Auf die gleiche Weise hat eine Seite, die vollständig geladen ist , auch viele Bedeutungen.)

Denken Sie auch daran, dass Selen vollständig Open Source ist. Nichts hindert Sie daran, das Repository erneut zu überprüfen und lokal zu überprüfen.

25
Arran

Ich würde darauf vertrauen, dass Selen herausfindet, ob ein Element angezeigt wird oder nicht. Wenn es nicht funktioniert, können Sie einen Fehler melden und/oder Probleme beheben und einen Patch bereitstellen.

Das macht die Methode (Aus dem aktuellen Selenium-Quellcode ):

/**
 * Determines whether an element is what a user would call "shown". This means
 * that the element is shown in the viewport of the browser, and only has
 * height and width greater than 0px, and that its visibility is not "hidden"
 * and its display property is not "none".
 * Options and Optgroup elements are treated as special cases: they are
 * considered shown iff they have a enclosing select element that is shown.
 *
 * @param {!Element} elem The element to consider.
 * @param {boolean=} opt_ignoreOpacity Whether to ignore the element's opacity
 *     when determining whether it is shown; defaults to false.
 * @return {boolean} Whether or not the element is visible.
 */
bot.dom.isShown = function(elem, opt_ignoreOpacity) {
  if (!bot.dom.isElement(elem)) {
    throw new Error('Argument to isShown must be of type Element');
  }

  // Option or optgroup is shown iff enclosing select is shown (ignoring the
  // select's opacity).
  if (bot.dom.isElement(elem, goog.dom.TagName.OPTION) ||
      bot.dom.isElement(elem, goog.dom.TagName.OPTGROUP)) {
    var select = /**@type {Element}*/ (goog.dom.getAncestor(elem, function(e) {
      return bot.dom.isElement(e, goog.dom.TagName.SELECT);
    }));
    return !!select && bot.dom.isShown(select, /*ignoreOpacity=*/true);
  }

  // Image map elements are shown if image that uses it is shown, and
  // the area of the element is positive.
  var imageMap = bot.dom.maybeFindImageMap_(elem);
  if (imageMap) {
    return !!imageMap.image &&
           imageMap.rect.width > 0 && imageMap.rect.height > 0 &&
           bot.dom.isShown(imageMap.image, opt_ignoreOpacity);
  }

  // Any hidden input is not shown.
  if (bot.dom.isElement(elem, goog.dom.TagName.INPUT) &&
      elem.type.toLowerCase() == 'hidden') {
    return false;
  }

  // Any NOSCRIPT element is not shown.
  if (bot.dom.isElement(elem, goog.dom.TagName.NOSCRIPT)) {
    return false;
  }

  // Any element with hidden visibility is not shown.
  if (bot.dom.getEffectiveStyle(elem, 'visibility') == 'hidden') {
    return false;
  }

  // Any element with a display style equal to 'none' or that has an ancestor
  // with display style equal to 'none' is not shown.
  function displayed(e) {
    if (bot.dom.getEffectiveStyle(e, 'display') == 'none') {
      return false;
    }
    var parent = bot.dom.getParentElement(e);
    return !parent || displayed(parent);
  }
  if (!displayed(elem)) {
    return false;
  }

  // Any transparent element is not shown.
  if (!opt_ignoreOpacity && bot.dom.getOpacity(elem) == 0) {
    return false;
  }

  // Any element with the hidden attribute or has an ancestor with the hidden
  // attribute is not shown
  function isHidden(e) {
    //IE does not support hidden attribute yet
    if (goog.userAgent.IE) {
      return true;
    }
    if (e.hasAttribute) {
      if (e.hasAttribute('hidden')){
        return false;
      }
    } else {
      return true;
    }
    var parent = bot.dom.getParentElement(e);
    return !parent || isHidden(parent);
  }

  if (!isHidden(elem)) {
    return false;
  }

  // Any element without positive size dimensions is not shown.
  function positiveSize(e) {
    var rect = bot.dom.getClientRect(e);
    if (rect.height > 0 && rect.width > 0) {
      return true;
    }
    // A vertical or horizontal SVG Path element will report zero width or
    // height but is "shown" if it has a positive stroke-width.
    if (bot.dom.isElement(e, 'PATH') && (rect.height > 0 || rect.width > 0)) {
      var strokeWidth = bot.dom.getEffectiveStyle(e, 'stroke-width');
      return !!strokeWidth && (parseInt(strokeWidth, 10) > 0);
    }
    // Zero-sized elements should still be considered to have positive size
    // if they have a child element or text node with positive size, unless
    // the element has an 'overflow' style of 'hidden'.
    return bot.dom.getEffectiveStyle(e, 'overflow') != 'hidden' &&
        goog.array.some(e.childNodes, function(n) {
          return n.nodeType == goog.dom.NodeType.TEXT ||
                 (bot.dom.isElement(n) && positiveSize(n));
        });
  }
  if (!positiveSize(elem)) {
    return false;
  }

  // Elements that are hidden by overflow are not shown.
  if (bot.dom.getOverflowState(elem) == bot.dom.OverflowState.HIDDEN) {
    return false;
  }

Ich bin mir nicht sicher, ob es wirklich einer weiteren Erklärung bedarf, aber die Kommentare sind ziemlich klar. Lassen Sie mich wissen, wenn Sie weitere Informationen hinzugefügt haben möchten.

28
Ardesco