@qawolf/web
Advanced tools
Comparing version 0.4.4 to 0.5.0
@@ -115,2 +115,3 @@ "use strict"; | ||
inputType: element.type || null, | ||
isContentEditable: element.isContentEditable, | ||
labels: exports.getLabels(element), | ||
@@ -117,0 +118,0 @@ name: element.name || null, |
@@ -1,1 +0,2 @@ | ||
export declare type Event = {}; | ||
import { Event } from "@qawolf/types"; | ||
export declare const isKeyEvent: (event: Event | null) => boolean | null; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isKeyEvent = (event) => event && | ||
event.isTrusted && | ||
(event.name === "keydown" || event.name === "keyup"); | ||
//# sourceMappingURL=event.js.map |
@@ -19,3 +19,3 @@ "use strict"; | ||
exports.queryActionElements = (action) => { | ||
const selector = action === "input" ? "input,select,textarea" : "*"; | ||
const selector = action === "type" ? "input,select,textarea,[contenteditable='true']" : "*"; | ||
return exports.queryVisibleElements(selector); | ||
@@ -25,4 +25,4 @@ }; | ||
let dataSelector = `[${dataAttribute}='${dataValue}']`; | ||
if (action === "input") { | ||
const selector = `input${dataSelector},select${dataSelector},textarea${dataSelector}`; | ||
if (action === "type") { | ||
const selector = `input${dataSelector},select${dataSelector},textarea${dataSelector},[contenteditable="true"]${dataSelector}`; | ||
return exports.queryVisibleElements(selector); | ||
@@ -29,0 +29,0 @@ } |
import * as element from "./element"; | ||
import * as event from "./event"; | ||
import * as find from "./find"; | ||
@@ -9,13 +10,15 @@ import * as match from "./match"; | ||
export declare type Match = Match; | ||
declare const compareArrays: (base?: string[] | null | undefined, compare?: string[] | null | undefined) => number, compareDescriptorKey: (key: "dataValue" | "title" | "ariaLabel" | "classList" | "href" | "iconContent" | "id" | "inputType" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "xpath", targetValue: string | string[] | null | undefined, compareValue: string | string[] | null | undefined) => { | ||
key: "dataValue" | "title" | "ariaLabel" | "classList" | "href" | "iconContent" | "id" | "inputType" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "xpath"; | ||
declare const isKeyEvent: (event: import("@qawolf/types").Event | null) => boolean | null; | ||
declare const compareArrays: (base?: string[] | null | undefined, compare?: string[] | null | undefined) => number, compareDescriptorKey: (key: "ariaLabel" | "classList" | "dataValue" | "href" | "iconContent" | "id" | "inputType" | "isContentEditable" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "title" | "xpath", targetValue: string | boolean | string[] | null | undefined, compareValue: string | boolean | string[] | null | undefined) => { | ||
key: "ariaLabel" | "classList" | "dataValue" | "href" | "iconContent" | "id" | "inputType" | "isContentEditable" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "title" | "xpath"; | ||
percent: number; | ||
}, compareDescriptors: (target: import("@qawolf/types").ElementDescriptor, compare: import("@qawolf/types").ElementDescriptor) => { | ||
key: "dataValue" | "title" | "ariaLabel" | "classList" | "href" | "iconContent" | "id" | "inputType" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "xpath"; | ||
key: "ariaLabel" | "classList" | "dataValue" | "href" | "iconContent" | "id" | "inputType" | "isContentEditable" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "title" | "xpath"; | ||
percent: number; | ||
}[], countPresentKeys: (descriptor: import("@qawolf/types").ElementDescriptor) => number, isNil: (value?: any) => boolean; | ||
declare const sleep: (milliseconds: number) => Promise<void>, waitFor: <T>(valueFn: () => T | null, timeoutMs: number, sleepMs?: number) => Promise<T | null>, waitUntil: (booleanFn: () => boolean, timeoutMs: number, sleepMs?: number) => Promise<void>; | ||
export { compareArrays, compareDescriptorKey, compareDescriptors, countPresentKeys, isNil, sleep, waitFor, waitUntil }; | ||
export { compareArrays, compareDescriptorKey, compareDescriptors, countPresentKeys, isKeyEvent, isNil, sleep, waitFor, waitUntil }; | ||
declare const webExports: { | ||
element: typeof element; | ||
event: typeof event; | ||
find: typeof find; | ||
@@ -22,0 +25,0 @@ match: typeof match; |
@@ -11,2 +11,3 @@ "use strict"; | ||
const element = __importStar(require("./element")); | ||
const event = __importStar(require("./event")); | ||
const find = __importStar(require("./find")); | ||
@@ -18,2 +19,4 @@ const match = __importStar(require("./match")); | ||
const xpath = __importStar(require("./xpath")); | ||
const { isKeyEvent } = event; | ||
exports.isKeyEvent = isKeyEvent; | ||
const { compareArrays, compareDescriptorKey, compareDescriptors, countPresentKeys, isNil } = match; | ||
@@ -31,2 +34,3 @@ exports.compareArrays = compareArrays; | ||
element, | ||
event, | ||
find, | ||
@@ -33,0 +37,0 @@ match, |
@@ -6,3 +6,3 @@ import { ElementDescriptor } from "@qawolf/types"; | ||
}; | ||
declare type DescriptorValue = string | string[] | null | undefined; | ||
declare type DescriptorValue = boolean | string | string[] | null | undefined; | ||
declare type MatchArgs = { | ||
@@ -24,4 +24,4 @@ dataAttribute: string | null; | ||
export declare const compareArrays: (base?: string[] | null | undefined, compare?: string[] | null | undefined) => number; | ||
export declare const compareDescriptorKey: (key: "dataValue" | "title" | "ariaLabel" | "classList" | "href" | "iconContent" | "id" | "inputType" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "xpath", targetValue: DescriptorValue, compareValue: DescriptorValue) => { | ||
key: "dataValue" | "title" | "ariaLabel" | "classList" | "href" | "iconContent" | "id" | "inputType" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "xpath"; | ||
export declare const compareDescriptorKey: (key: "ariaLabel" | "classList" | "dataValue" | "href" | "iconContent" | "id" | "inputType" | "isContentEditable" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "title" | "xpath", targetValue: DescriptorValue, compareValue: DescriptorValue) => { | ||
key: "ariaLabel" | "classList" | "dataValue" | "href" | "iconContent" | "id" | "inputType" | "isContentEditable" | "labels" | "name" | "parentText" | "placeholder" | "tagName" | "innerText" | "title" | "xpath"; | ||
percent: number; | ||
@@ -28,0 +28,0 @@ }; |
@@ -169,2 +169,3 @@ var qawolf = (function (exports) { | ||
inputType: element.type || null, | ||
isContentEditable: element.isContentEditable, | ||
labels: getLabels(element), | ||
@@ -192,2 +193,13 @@ name: element.name || null, | ||
var isKeyEvent = function (event) { | ||
return event && | ||
event.isTrusted && | ||
(event.name === "keydown" || event.name === "keyup"); | ||
}; | ||
var event = /*#__PURE__*/Object.freeze({ | ||
__proto__: null, | ||
isKeyEvent: isKeyEvent | ||
}); | ||
/*! ***************************************************************************** | ||
@@ -433,3 +445,3 @@ Copyright (c) Microsoft Corporation. All rights reserved. | ||
var queryActionElements = function (action) { | ||
var selector = action === "input" ? "input,select,textarea" : "*"; | ||
var selector = action === "type" ? "input,select,textarea,[contenteditable='true']" : "*"; | ||
return queryVisibleElements(selector); | ||
@@ -440,4 +452,4 @@ }; | ||
var dataSelector = "[" + dataAttribute + "='" + dataValue + "']"; | ||
if (action === "input") { | ||
var selector = "input" + dataSelector + ",select" + dataSelector + ",textarea" + dataSelector; | ||
if (action === "type") { | ||
var selector = "input" + dataSelector + ",select" + dataSelector + ",textarea" + dataSelector + ",[contenteditable=\"true\"]" + dataSelector; | ||
return queryVisibleElements(selector); | ||
@@ -548,16 +560,20 @@ } | ||
}; | ||
Recorder.prototype.listen = function (eventName, handler) { | ||
document.addEventListener(eventName, handler, { | ||
capture: true, | ||
passive: true | ||
}); | ||
this._onDispose.push(function () { | ||
return document.removeEventListener(eventName, handler); | ||
}); | ||
}; | ||
Recorder.prototype.recordEvent = function (eventName, handler) { | ||
var _this = this; | ||
var listener = function (ev) { | ||
this.listen(eventName, function (ev) { | ||
var event = handler(ev); | ||
if (!event) | ||
return; | ||
console.log("Recorder: " + eventName + " event", ev, ev.target, "recorded:", event); | ||
_this._sendEvent(event); | ||
}; | ||
document.addEventListener(eventName, listener, { | ||
capture: true, | ||
passive: true | ||
}); | ||
this._onDispose.push(function () { | ||
return document.removeEventListener(eventName, listener); | ||
}); | ||
}; | ||
@@ -567,12 +583,15 @@ Recorder.prototype.recordEvents = function () { | ||
this.recordEvent("click", function (event) { return ({ | ||
action: "click", | ||
isTrusted: event.isTrusted, | ||
name: "click", | ||
target: getDescriptor(event.target, _this._dataAttribute), | ||
time: Date.now() | ||
}); }); | ||
var onInput = function (event) { | ||
this.recordEvent("input", function (event) { | ||
var element = event.target; | ||
// ignore input events except on selects | ||
if (element.tagName.toLowerCase() !== "select") | ||
return; | ||
return { | ||
action: "input", | ||
isTrusted: event.isTrusted, | ||
name: "input", | ||
target: getDescriptor(element, _this._dataAttribute), | ||
@@ -582,8 +601,47 @@ time: Date.now(), | ||
}; | ||
}; | ||
this.recordEvent("change", onInput); | ||
this.recordEvent("input", onInput); | ||
}); | ||
this.recordEvent("keydown", function (event) { return ({ | ||
isTrusted: event.isTrusted, | ||
name: "keydown", | ||
target: getDescriptor(event.target, _this._dataAttribute), | ||
time: Date.now(), | ||
value: event.code | ||
}); }); | ||
this.recordEvent("keyup", function (event) { return ({ | ||
isTrusted: event.isTrusted, | ||
name: "keyup", | ||
target: getDescriptor(event.target, _this._dataAttribute), | ||
time: Date.now(), | ||
value: event.code | ||
}); }); | ||
this.recordEvent("paste", function (event) { | ||
if (!event.clipboardData) | ||
return; | ||
return { | ||
isTrusted: event.isTrusted, | ||
name: "paste", | ||
target: getDescriptor(event.target, _this._dataAttribute), | ||
time: Date.now(), | ||
value: event.clipboardData.getData("text") | ||
}; | ||
}); | ||
this.recordScrollEvent(); | ||
}; | ||
Recorder.prototype.recordScrollEvent = function () { | ||
var _this = this; | ||
var lastWheelEvent = null; | ||
this.listen("wheel", function (ev) { return (lastWheelEvent = ev); }); | ||
// We record the scroll event and not the wheel event | ||
// because it fires after the element.scrollLeft & element.scrollTop are updated | ||
this.recordEvent("scroll", function (event) { | ||
if (!lastWheelEvent || event.timeStamp - lastWheelEvent.timeStamp > 100) { | ||
// We record mouse wheel initiated scrolls only | ||
// to avoid recording system initiated scrolls (after selecting an item/etc). | ||
// This will not capture scrolls triggered by the keyboard (PgUp/PgDown/Space) | ||
// however we already record key events so that encompasses those. | ||
console.log("ignore non-wheel scroll event", event); | ||
return; | ||
} | ||
var element = event.target; | ||
if (event.target === document) { | ||
if (event.target === document || event.target === document.body) { | ||
element = (document.scrollingElement || | ||
@@ -593,4 +651,4 @@ document.documentElement); | ||
return { | ||
action: "scroll", | ||
isTrusted: event.isTrusted, | ||
name: "scroll", | ||
target: getDescriptor(element, _this._dataAttribute), | ||
@@ -652,2 +710,3 @@ time: Date.now(), | ||
// export the isomorphic (node & browser) module for node | ||
var isKeyEvent$1 = isKeyEvent; | ||
var compareArrays$1 = compareArrays, compareDescriptorKey$1 = compareDescriptorKey, compareDescriptors$1 = compareDescriptors, countPresentKeys$1 = countPresentKeys, isNil$1 = isNil; | ||
@@ -658,2 +717,3 @@ var sleep$1 = sleep, waitFor$1 = waitFor, waitUntil$1 = waitUntil; | ||
element: element, | ||
event: event, | ||
find: find, | ||
@@ -674,2 +734,3 @@ match: match, | ||
exports.countPresentKeys = countPresentKeys$1; | ||
exports.isKeyEvent = isKeyEvent$1; | ||
exports.isNil = isNil$1; | ||
@@ -676,0 +737,0 @@ exports.sleep = sleep$1; |
@@ -9,5 +9,7 @@ import * as types from "@qawolf/types"; | ||
dispose(): void; | ||
private listen; | ||
private recordEvent; | ||
private recordEvents; | ||
private recordScrollEvent; | ||
} | ||
export {}; |
@@ -14,26 +14,32 @@ "use strict"; | ||
} | ||
listen(eventName, handler) { | ||
document.addEventListener(eventName, handler, { | ||
capture: true, | ||
passive: true | ||
}); | ||
this._onDispose.push(() => document.removeEventListener(eventName, handler)); | ||
} | ||
recordEvent(eventName, handler) { | ||
const listener = (ev) => { | ||
this.listen(eventName, (ev) => { | ||
const event = handler(ev); | ||
if (!event) | ||
return; | ||
console.log(`Recorder: ${eventName} event`, ev, ev.target, "recorded:", event); | ||
this._sendEvent(event); | ||
}; | ||
document.addEventListener(eventName, listener, { | ||
capture: true, | ||
passive: true | ||
}); | ||
this._onDispose.push(() => document.removeEventListener(eventName, listener)); | ||
} | ||
recordEvents() { | ||
this.recordEvent("click", event => ({ | ||
action: "click", | ||
isTrusted: event.isTrusted, | ||
name: "click", | ||
target: element_1.getDescriptor(event.target, this._dataAttribute), | ||
time: Date.now() | ||
})); | ||
const onInput = (event) => { | ||
this.recordEvent("input", event => { | ||
const element = event.target; | ||
if (element.tagName.toLowerCase() !== "select") | ||
return; | ||
return { | ||
action: "input", | ||
isTrusted: event.isTrusted, | ||
name: "input", | ||
target: element_1.getDescriptor(element, this._dataAttribute), | ||
@@ -43,8 +49,40 @@ time: Date.now(), | ||
}; | ||
}; | ||
this.recordEvent("change", onInput); | ||
this.recordEvent("input", onInput); | ||
}); | ||
this.recordEvent("keydown", event => ({ | ||
isTrusted: event.isTrusted, | ||
name: "keydown", | ||
target: element_1.getDescriptor(event.target, this._dataAttribute), | ||
time: Date.now(), | ||
value: event.code | ||
})); | ||
this.recordEvent("keyup", event => ({ | ||
isTrusted: event.isTrusted, | ||
name: "keyup", | ||
target: element_1.getDescriptor(event.target, this._dataAttribute), | ||
time: Date.now(), | ||
value: event.code | ||
})); | ||
this.recordEvent("paste", event => { | ||
if (!event.clipboardData) | ||
return; | ||
return { | ||
isTrusted: event.isTrusted, | ||
name: "paste", | ||
target: element_1.getDescriptor(event.target, this._dataAttribute), | ||
time: Date.now(), | ||
value: event.clipboardData.getData("text") | ||
}; | ||
}); | ||
this.recordScrollEvent(); | ||
} | ||
recordScrollEvent() { | ||
let lastWheelEvent = null; | ||
this.listen("wheel", ev => (lastWheelEvent = ev)); | ||
this.recordEvent("scroll", event => { | ||
if (!lastWheelEvent || event.timeStamp - lastWheelEvent.timeStamp > 100) { | ||
console.log("ignore non-wheel scroll event", event); | ||
return; | ||
} | ||
let element = event.target; | ||
if (event.target === document) { | ||
if (event.target === document || event.target === document.body) { | ||
element = (document.scrollingElement || | ||
@@ -54,4 +92,4 @@ document.documentElement); | ||
return { | ||
action: "scroll", | ||
isTrusted: event.isTrusted, | ||
name: "scroll", | ||
target: element_1.getDescriptor(element, this._dataAttribute), | ||
@@ -58,0 +96,0 @@ time: Date.now(), |
{ | ||
"name": "@qawolf/web", | ||
"description": "qawolf web library", | ||
"version": "0.4.4", | ||
"version": "0.5.0", | ||
"license": "BSD-3.0", | ||
@@ -27,3 +27,3 @@ "main": "./lib/index.js", | ||
"devDependencies": { | ||
"@qawolf/types": "^0.4.4", | ||
"@qawolf/types": "^0.5.0", | ||
"rollup": "^1.23.1", | ||
@@ -34,3 +34,3 @@ "rollup-plugin-commonjs": "^10.1.0", | ||
}, | ||
"gitHead": "46e1d99d06c223f1fa8281e957856da4a7c152f1" | ||
"gitHead": "ab0de314c354a4adb5889edd2a35a98ea7708798" | ||
} |
@@ -146,2 +146,3 @@ import { ElementDescriptor } from "@qawolf/types"; | ||
inputType: (element as HTMLInputElement).type || null, | ||
isContentEditable: element.isContentEditable, | ||
labels: getLabels(element), | ||
@@ -148,0 +149,0 @@ name: (element as HTMLInputElement).name || null, |
@@ -17,3 +17,4 @@ import { Action, Locator } from "@qawolf/types"; | ||
export const queryActionElements = (action: Action): HTMLElement[] => { | ||
const selector = action === "input" ? "input,select,textarea" : "*"; | ||
const selector = | ||
action === "type" ? "input,select,textarea,[contenteditable='true']" : "*"; | ||
@@ -29,4 +30,4 @@ return queryVisibleElements(selector); | ||
let dataSelector = `[${dataAttribute}='${dataValue}']`; | ||
if (action === "input") { | ||
const selector = `input${dataSelector},select${dataSelector},textarea${dataSelector}`; | ||
if (action === "type") { | ||
const selector = `input${dataSelector},select${dataSelector},textarea${dataSelector},[contenteditable="true"]${dataSelector}`; | ||
return queryVisibleElements(selector); | ||
@@ -33,0 +34,0 @@ } |
import * as element from "./element"; | ||
import * as event from "./event"; | ||
import * as find from "./find"; | ||
@@ -13,2 +14,3 @@ import * as match from "./match"; | ||
// export the isomorphic (node & browser) module for node | ||
const { isKeyEvent } = event; | ||
const { | ||
@@ -27,2 +29,3 @@ compareArrays, | ||
countPresentKeys, | ||
isKeyEvent, | ||
isNil, | ||
@@ -37,2 +40,3 @@ sleep, | ||
element, | ||
event, | ||
find, | ||
@@ -39,0 +43,0 @@ match, |
@@ -10,3 +10,3 @@ import { ElementDescriptor } from "@qawolf/types"; | ||
type DescriptorValue = string | string[] | null | undefined; | ||
type DescriptorValue = boolean | string | string[] | null | undefined; | ||
@@ -13,0 +13,0 @@ type MatchArgs = { |
@@ -22,8 +22,24 @@ import * as types from "@qawolf/types"; | ||
private listen<K extends keyof DocumentEventMap>( | ||
eventName: K, | ||
handler: (ev: DocumentEventMap[K]) => any | ||
) { | ||
document.addEventListener(eventName, handler, { | ||
capture: true, | ||
passive: true | ||
}); | ||
this._onDispose.push(() => | ||
document.removeEventListener(eventName, handler) | ||
); | ||
} | ||
private recordEvent<K extends keyof DocumentEventMap>( | ||
eventName: K, | ||
handler: (ev: DocumentEventMap[K]) => types.Event | ||
handler: (ev: DocumentEventMap[K]) => types.Event | undefined | ||
) { | ||
const listener = (ev: DocumentEventMap[K]) => { | ||
this.listen(eventName, (ev: DocumentEventMap[K]) => { | ||
const event = handler(ev); | ||
if (!event) return; | ||
console.log( | ||
@@ -37,12 +53,3 @@ `Recorder: ${eventName} event`, | ||
this._sendEvent(event); | ||
}; | ||
document.addEventListener(eventName, listener, { | ||
capture: true, | ||
passive: true | ||
}); | ||
this._onDispose.push(() => | ||
document.removeEventListener(eventName, listener) | ||
); | ||
} | ||
@@ -52,4 +59,4 @@ | ||
this.recordEvent("click", event => ({ | ||
action: "click", | ||
isTrusted: event.isTrusted, | ||
name: "click", | ||
target: getDescriptor(event.target as HTMLElement, this._dataAttribute), | ||
@@ -59,19 +66,65 @@ time: Date.now() | ||
const onInput = (event: Event) => { | ||
this.recordEvent("input", event => { | ||
const element = event.target as HTMLInputElement; | ||
// ignore input events except on selects | ||
if (element.tagName.toLowerCase() !== "select") return; | ||
return { | ||
action: "input", | ||
isTrusted: event.isTrusted, | ||
name: "input", | ||
target: getDescriptor(element, this._dataAttribute), | ||
time: Date.now(), | ||
value: element.value | ||
} as types.InputEvent; | ||
}; | ||
}; | ||
}); | ||
this.recordEvent("change", onInput); | ||
this.recordEvent("input", onInput); | ||
this.recordEvent("keydown", event => ({ | ||
isTrusted: event.isTrusted, | ||
name: "keydown", | ||
target: getDescriptor(event.target as HTMLElement, this._dataAttribute), | ||
time: Date.now(), | ||
value: event.code | ||
})); | ||
this.recordEvent("keyup", event => ({ | ||
isTrusted: event.isTrusted, | ||
name: "keyup", | ||
target: getDescriptor(event.target as HTMLElement, this._dataAttribute), | ||
time: Date.now(), | ||
value: event.code | ||
})); | ||
this.recordEvent("paste", event => { | ||
if (!event.clipboardData) return; | ||
return { | ||
isTrusted: event.isTrusted, | ||
name: "paste", | ||
target: getDescriptor(event.target as HTMLElement, this._dataAttribute), | ||
time: Date.now(), | ||
value: event.clipboardData.getData("text") | ||
}; | ||
}); | ||
this.recordScrollEvent(); | ||
} | ||
private recordScrollEvent() { | ||
let lastWheelEvent: WheelEvent | null = null; | ||
this.listen("wheel", ev => (lastWheelEvent = ev)); | ||
// We record the scroll event and not the wheel event | ||
// because it fires after the element.scrollLeft & element.scrollTop are updated | ||
this.recordEvent("scroll", event => { | ||
if (!lastWheelEvent || event.timeStamp - lastWheelEvent.timeStamp > 100) { | ||
// We record mouse wheel initiated scrolls only | ||
// to avoid recording system initiated scrolls (after selecting an item/etc). | ||
// This will not capture scrolls triggered by the keyboard (PgUp/PgDown/Space) | ||
// however we already record key events so that encompasses those. | ||
console.log("ignore non-wheel scroll event", event); | ||
return; | ||
} | ||
let element = event.target as HTMLElement; | ||
if (event.target === document) { | ||
if (event.target === document || event.target === document.body) { | ||
element = (document.scrollingElement || | ||
@@ -82,4 +135,4 @@ document.documentElement) as HTMLElement; | ||
return { | ||
action: "scroll", | ||
isTrusted: event.isTrusted, | ||
name: "scroll", | ||
target: getDescriptor(element, this._dataAttribute), | ||
@@ -86,0 +139,0 @@ time: Date.now(), |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
121880
63
2361