Module: Applitools::Selenium::DomCapture

Extended by:
DomCapture
Included in:
DomCapture
Defined in:
lib/applitools/selenium/dom_capture/dom_capture.rb,
lib/applitools/selenium/dom_capture/dom_capture_script.rb

Constant Summary collapse

CSS_DOWNLOAD_TIMEOUT =

2 seconds

2
DOM_CAPTURE_TIMEOUT =

10 seconds

10
CSS_CAPTURE_SCRIPT =
<<-SCRIPT
  function extractCssResources() {
    return Array.from(document.querySelectorAll('link[rel="stylesheet"],style')).map(el => {
      if (el.tagName.toUpperCase() === 'LINK') {
          return {"href": el.getAttribute('href')};
      } else {
          return {"text": el.textContent};
      }
    });
  }
  return extractCssResources();
SCRIPT
DOM_CAPTURE_SCRIPT =
<<-SCRIPT
  function captureFrame({ styleProps, attributeProps, rectProps, ignoredTagNames }) {
    const NODE_TYPES = {
      ELEMENT: 1,
      TEXT: 3,
    };
    function filter(x) {
      return !!x;
    }
    function notEmptyObj(obj) {
      return Object.keys(obj).length ? obj : undefined;
    }
    function iframeToJSON(el) {
      const obj = elementToJSON(el);
      try {
        if (el.contentDocument) {
          obj.childNodes = [captureNode(el.contentDocument.documentElement)];
        }
      } catch (ex) {
      } finally {
        return obj;
      }
    }
    function elementToJSON(el) {
      const tagName = el.tagName.toUpperCase();
      if (ignoredTagNames.indexOf(tagName) > -1) return null;
      const computedStyle = window.getComputedStyle(el);
      const boundingClientRect = el.getBoundingClientRect();
      const style = {};
      for (const p of styleProps) style[p] = computedStyle.getPropertyValue(p);
      const rect = {};
      for (const p of rectProps) rect[p] = boundingClientRect[p];
      const attributes = {};
      if (!attributeProps) {
        if (el.hasAttributes()) {
          var attrs = el.attributes;
          for (const p of attrs) {
            attributes[p.name] = p.value;
          }
        }
      }
      else {
        if (attributeProps.all) {
          for (const p of attributeProps.all) {
            if (el.hasAttribute(p)) attributes[p] = el.getAttribute(p);
          }
        }
        if (attributeProps[tagName]) {
          for (const p of attributeProps[tagName]) {
            if (el.hasAttribute(p)) attributes[p] = el.getAttribute(p);
          }
        }
      }
      return {
        tagName,
        style: notEmptyObj(style),
        rect: notEmptyObj(rect),
        attributes: notEmptyObj(attributes),
        childNodes: Array.prototype.map.call(el.childNodes, captureNode).filter(filter),
      };
    }
    function captureTextNode(node) {
      return {
        tagName: '#text',
        text: node.textContent,
      };
    }
    function captureNode(node) {
      switch (node.nodeType) {
        case NODE_TYPES.TEXT:
          return captureTextNode(node);
        case NODE_TYPES.ELEMENT:
          if (node.tagName.toUpperCase() === 'IFRAME') {
            return iframeToJSON(node);
          } else {
            return elementToJSON(node);
          }
        default:
          return null;
      }
    }
    return captureNode(document.documentElement);
  }
  return captureFrame(arguments[0]);
SCRIPT

Instance Method Summary collapse

Instance Method Details

#get_window_dom(driver, logger) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/applitools/selenium/dom_capture/dom_capture.rb', line 15

def get_window_dom(driver, logger)
  args_obj = {
    'styleProps' => %w(
      background-color background-image background-size color border-width
      border-color border-style padding margin
    ),
    'attributeProps' => nil,
    'rectProps' => %w(width height top left),
    'ignoredTagNames' => %w(HEAD SCRIPT)
  }
  dom_tree = ''
  if Timeout.respond_to?(:timeout)
    Timeout.timeout(DOM_CAPTURE_TIMEOUT) do
      dom_tree = driver.execute_script(Applitools::Selenium::DomCapture::DOM_CAPTURE_SCRIPT, args_obj)
      get_frame_dom(driver, { 'childNodes' => [dom_tree], 'tagName' => 'OUTER_HTML' }, logger)
    end
  else
    timeout(DOM_CAPTURE_TIMEOUT) do
      dom_tree = driver.execute_script(Applitools::Selenium::DomCapture::DOM_CAPTURE_SCRIPT, args_obj)
      get_frame_dom(driver, { 'childNodes' => [dom_tree], 'tagName' => 'OUTER_HTML' }, logger)
    end
  end
  dom_tree
end