New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@applitools/dom-utils

Package Overview
Dependencies
Maintainers
12
Versions
78
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@applitools/dom-utils - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

231

lib/DomCapture.js

@@ -7,8 +7,7 @@ 'use strict';

const url = require('url');
const isAbsoluteUrl = require('is-absolute-url');
const axios = require('axios');
const cssParser = require('css');
const shadyCss = require('shady-css-parser');
const cssUrlParser = require('css-url-parser');
const { Location, PerformanceUtils } = require('@applitools/eyes.sdk.core');
const { Location, GeneralUtils, PerformanceUtils } = require('@applitools/eyes.sdk.core');

@@ -28,2 +27,6 @@ class DomCapture {

constructor() {
this._frameBundledCssPromises = [];
}
/**

@@ -42,3 +45,3 @@ * @param {Logger} logger A Logger instance.

const dom = await this.getWindowDom(logger, driver);
const dom = await DomCapture.getWindowDom(logger, driver);

@@ -57,3 +60,3 @@ if (positionProvider) {

*/
static getWindowDom(logger, driver) {
static async getWindowDom(logger, driver) {
const argsObj = {

@@ -72,10 +75,2 @@ styleProps: [

attributeProps: null,
/*
[
{all: ["id", "class"]},
{IMG: ["src"]},
{IFRAME: ["src"]},
{A: ["href"]},
]
*/
rectProps: [

@@ -87,6 +82,15 @@ 'width',

],
ignoredTagNames: ['HEAD', 'SCRIPT'],
ignoredTagNames: [
'HEAD',
'SCRIPT',
],
};
return DomCapture._getFrameDom(logger, driver, argsObj);
const json = await driver.executeScript(DomCapture.CAPTURE_FRAME_SCRIPT, argsObj);
const domTree = JSON.parse(json);
const domCapture = new DomCapture();
await domCapture._getFrameDom(logger, driver, { childNodes: [domTree], tagName: 'OUTER_HTML' });
await Promise.all(domCapture._frameBundledCssPromises);
return domTree;
}

@@ -97,80 +101,55 @@

* @param {EyesWebDriver} driver
* @param {object} argsObj
* @param {object} domTree
* @return {Promise.<object>}
* @private
*/
static async _getFrameDom(logger, driver, argsObj) {
try {
const json = await driver.executeScript(DomCapture.CAPTURE_FRAME_SCRIPT, argsObj);
const currentUrl = await driver.getCurrentUrl();
async _getFrameDom(logger, driver, domTree) {
const tagName = domTree.tagName;
const domTree = JSON.parse(json);
if (!tagName) {
return;
}
await DomCapture._traverseDomTree(logger, driver, argsObj, domTree, -1, currentUrl);
let frameIndex = 0;
return domTree;
} catch (e) {
throw new Error(`Error: ${e}`);
}
await this._loop(logger, driver, domTree, async domSubTree => {
await driver.switchTo().frame(frameIndex);
await this._getFrameDom(logger, driver, domSubTree);
await driver.switchTo().parentFrame();
frameIndex += 1;
});
}
/**
* @param {Logger} logger
* @param {EyesWebDriver} driver
* @param {object} argsObj
* @param {object} domTree
* @param {number} frameIndex
* @param {string} baseUri
* @param {function} fn
* @return {Promise<void>}
* @private
*/
static async _traverseDomTree(logger, driver, argsObj, domTree, frameIndex, baseUri) {
if (!domTree.tagName) {
async _loop(logger, driver, domTree, fn) {
const childNodes = domTree.childNodes;
if (!childNodes) {
return;
}
const tagNameObj = domTree.tagName;
const iterateChildNodes = async nodeChilds => {
for (const node of nodeChilds) {
if (node && node.tagName.toUpperCase() === 'IFRAME') {
await fn(node);
} else {
if (node && node.tagName.toUpperCase() === 'HTML') {
await this._getFrameBundledCss(logger, driver, node);
}
if (frameIndex > -1) {
let timeStart = PerformanceUtils.start();
await driver.switchTo().frame(frameIndex);
logger.verbose(`switching to frame took ${timeStart.end().summary}`);
timeStart = PerformanceUtils.start();
const json = await driver.executeScript(DomCapture.CAPTURE_FRAME_SCRIPT, argsObj);
logger.verbose(`executing javascript to capture frame's script took ${timeStart.end().summary}`);
const dom = JSON.parse(json);
domTree.childNodes = dom;
let srcUrl = null;
if (domTree.attributes) {
const attrsNodeObj = domTree.attributes;
const attrsNode = attrsNodeObj;
if (attrsNode.src) {
const srcUrlObj = attrsNode.src;
srcUrl = srcUrlObj.toString();
if (node.childNodes) {
await iterateChildNodes(node.childNodes);
}
}
}
if (srcUrl == null) {
logger.verbose('WARNING! IFRAME WITH NO SRC');
}
};
const srcUri = url.resolve(baseUri, srcUrl);
await DomCapture._traverseDomTree(logger, driver, argsObj, dom, -1, srcUri);
timeStart = PerformanceUtils.start();
await driver.switchTo().parentFrame();
logger.verbose(`switching to parent frame took ${timeStart.end().summary}`);
}
const tagName = tagNameObj;
const isHTML = tagName.toUpperCase() === 'HTML';
if (isHTML) {
const css = await DomCapture.getFrameBundledCss(logger, driver, baseUri);
domTree.css = css;
}
await DomCapture._loop(logger, driver, argsObj, domTree, baseUri);
await iterateChildNodes(childNodes);
}

@@ -181,38 +160,19 @@

* @param {EyesWebDriver} driver
* @param {object} argsObj
* @param {object} domTree
* @param {string} baseUri
* @param node
* @return {Promise<void>}
* @private
*/
static async _loop(logger, driver, argsObj, domTree, baseUri) {
if (!domTree.childNodes) {
return;
async _getFrameBundledCss(logger, driver, node) {
const currentUrl = await driver.getCurrentUrl();
if (!GeneralUtils.isAbsoluteUrl(currentUrl)) {
logger.verbose('WARNING! Base URL is not an absolute URL!');
}
const childNodes = domTree.childNodes;
let index = 0;
const timeStart = PerformanceUtils.start();
for (const node of childNodes) {
const domSubTree = node;
if (domSubTree) {
const tagName = domSubTree.tagName;
const isIframe = tagName.toUpperCase() === 'IFRAME';
const result = await driver.executeScript(DomCapture.CAPTURE_CSSOM_SCRIPT);
logger.verbose(`executing javascript to capture css took ${timeStart.end().summary}`);
if (isIframe) {
await DomCapture._traverseDomTree(logger, driver, argsObj, domSubTree, index, baseUri);
index += 1;
} else {
const childSubNodesObj = domSubTree.childNodes;
if (!childSubNodesObj || childSubNodesObj.length === 0) {
continue;
}
await DomCapture._traverseDomTree(logger, driver, argsObj, domSubTree, -1, baseUri);
return;
}
}
}
logger.verbose(`looping through ${childNodes.length} child nodes (out of which ${index} inner iframes) took ${timeStart.end().summary}`);
const promise = this._processFrameBundledCss(logger, driver, currentUrl, node, result);
this._frameBundledCssPromises.push(promise);
}

@@ -223,16 +183,12 @@

* @param {EyesWebDriver} driver
* @param {string} baseUri
* @return {Promise<string>}
* @param {string} currentUrl
* @param node
* @param result
* @return {Promise<void>}
* @private
*/
static async getFrameBundledCss(logger, driver, baseUri) {
if (!isAbsoluteUrl(baseUri)) {
logger.verbose('WARNING! Base URL is not an absolute URL!');
}
async _processFrameBundledCss(logger, driver, currentUrl, node, result) {
let sb = '';
let timeStart = PerformanceUtils.start();
const result = await driver.executeScript(DomCapture.CAPTURE_CSSOM_SCRIPT);
logger.verbose(`executing javascript to capture css took ${timeStart.end().summary}`);
for (const item of result) {
timeStart = PerformanceUtils.start();
let timeStart = PerformanceUtils.start();
const kind = item.substring(0, 5);

@@ -243,7 +199,7 @@ const value = item.substring(5);

if (kind === 'text:') {
css = await DomCapture._parseAndSerializeCss(logger, baseUri, value);
css = await this._parseAndSerializeCss(logger, currentUrl, value);
} else {
css = await DomCapture._downloadCss(logger, baseUri, value);
css = await this._downloadCss(logger, currentUrl, value);
}
css = await DomCapture._parseAndSerializeCss(logger, baseUri, css);
css = await this._parseAndSerializeCss(logger, currentUrl, css);
timeStart = PerformanceUtils.start();

@@ -253,3 +209,4 @@ sb += css;

}
return sb;
node.css = sb;
}

@@ -264,8 +221,14 @@

*/
static async _parseAndSerializeCss(logger, baseUri, css) {
async _parseAndSerializeCss(logger, baseUri, css) {
const timeStart = PerformanceUtils.start();
const stylesheet = cssParser.parse(css);
let stylesheet;
try {
const parser = new shadyCss.Parser();
stylesheet = parser.parse(css);
} catch (ignored) {
return '';
}
logger.verbose(`parsing CSS string took ${timeStart.end().summary}`);
css = await DomCapture._serializeCss(logger, baseUri, stylesheet.stylesheet);
css = await this._serializeCss(logger, baseUri, stylesheet);
return css;

@@ -281,3 +244,3 @@ }

*/
static async _serializeCss(logger, baseUri, stylesheet) {
async _serializeCss(logger, baseUri, stylesheet) {
const timeStart = PerformanceUtils.start();

@@ -289,11 +252,11 @@ let sb = '';

let addAsIs = true;
if (ruleSet.type === 'import') {
if (ruleSet.name === 'import') {
logger.verbose('encountered @import rule');
const href = cssUrlParser(ruleSet.import);
css = await DomCapture._downloadCss(logger, baseUri, href[0]);
const href = cssUrlParser(ruleSet.parameters);
css = await this._downloadCss(logger, baseUri, href[0]);
css = css.trim();
logger.verbose('imported CSS (whitespaces trimmed) length: {0}', css.length);
logger.verbose(`imported CSS (whitespaces trimmed) length: ${css.length}`);
addAsIs = css.length === 0;
if (!addAsIs) {
css = await DomCapture._parseAndSerializeCss(logger, baseUri, css);
css = await this._parseAndSerializeCss(logger, baseUri, css);
sb += css;

@@ -305,10 +268,6 @@ }

const node = {
stylesheet: {
rules: [ruleSet],
},
rules: [ruleSet],
};
sb += cssParser.stringify(node, { compress: true });
// sb += ruleSet.toString();
// sb += css;
const stringifier = new shadyCss.Stringifier();
sb += stringifier.stringify(ruleSet);
}

@@ -329,8 +288,8 @@ }

*/
static async _downloadCss(logger, baseUri, value, retriesCount = 1) {
async _downloadCss(logger, baseUri, value, retriesCount = 1) {
try {
logger.verbose('Given URL to download: {0}', value);
logger.verbose(`Given URL to download: ${value}`);
// let href = cssParser.parse(value);
let href = value;
if (!isAbsoluteUrl(href)) {
if (!GeneralUtils.isAbsoluteUrl(href)) {
href = url.resolve(baseUri, href.toString());

@@ -347,4 +306,4 @@ }

if (retriesCount > 0) {
retriesCount--;
return DomCapture._downloadCss(logger, baseUri, value, retriesCount);
retriesCount -= 1;
return this._downloadCss(logger, baseUri, value, retriesCount);
}

@@ -351,0 +310,0 @@ return '';

{
"name": "@applitools/dom-utils",
"version": "1.0.0",
"version": "1.1.0",
"description": "Applitools DOM Utils is a shared utility package",

@@ -27,13 +27,12 @@ "keywords": [

"dependencies": {
"@applitools/eyes.sdk.core": "^2.2.1",
"@applitools/eyes.sdk.core": "^2.2.2",
"axios": "^0.18.0",
"css": "^2.2.4",
"css-url-parser": "^1.1.3",
"is-absolute-url": "^2.1.0"
"shady-css-parser": "^0.1.0"
},
"devDependencies": {
"chromedriver": "^2.43.1",
"dateformat": "^3.0.3",
"mocha": "^5.2.0",
"dateformat": "^3.0.3",
"selenium-webdriver": "^3.6.0",
"chromedriver": "^2.42.0"
"selenium-webdriver": "^4.0.0-alpha.1"
},

@@ -40,0 +39,0 @@ "scripts": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc