@progress/kendo-e2e
Version:
Kendo UI end-to-end test utilities.
186 lines • 9.26 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UIComponent = exports.FUZZ_TEST_EXPECTATIONS = exports.MALICIOUS_INPUT_PAYLOADS = exports.BUFFER_OVERFLOW_PAYLOADS = exports.HTML_INJECTION_PAYLOADS = exports.PATH_TRAVERSAL_PAYLOADS = exports.COMMAND_INJECTION_PAYLOADS = exports.SQL_INJECTION_PAYLOADS = exports.XSS_PAYLOADS = void 0;
const selenium_1 = require("../selenium");
exports.XSS_PAYLOADS = [
`"><script>alert('XSS')</script>`,
`<IMG SRC="javascript:alert('XSS');">`,
`<svg onload=alert(1)>`,
`"><img src=x onerror=alert(1)>`,
];
exports.SQL_INJECTION_PAYLOADS = [
`' OR '1'='1`,
`"; DROP TABLE users; --`,
`" UNION SELECT null, username, password FROM users --`,
`admin' --`,
];
exports.COMMAND_INJECTION_PAYLOADS = [
`; ls -la`,
`| cat /etc/passwd`,
`$(reboot)`,
`&& rm -rf /`,
];
exports.PATH_TRAVERSAL_PAYLOADS = [
`../../../../etc/passwd`,
`..\..\..\..\windows\system32\cmd.exe`,
`/etc/shadow`,
`../../boot.ini`,
];
exports.HTML_INJECTION_PAYLOADS = [
`<h1>Hacked!</h1>`,
`<iframe src="http://evil.com"></iframe>`,
`<marquee>Security Broken</marquee>`,
`<link rel="stylesheet" href="http://evil.com/bad.css">`,
`<img src="/imagepath" onerror="alert('xss')">`
];
exports.BUFFER_OVERFLOW_PAYLOADS = [
"A".repeat(5000),
"\x42".repeat(10000),
];
exports.MALICIOUS_INPUT_PAYLOADS = [
exports.XSS_PAYLOADS,
exports.SQL_INJECTION_PAYLOADS,
exports.COMMAND_INJECTION_PAYLOADS,
exports.PATH_TRAVERSAL_PAYLOADS,
exports.HTML_INJECTION_PAYLOADS,
exports.BUFFER_OVERFLOW_PAYLOADS,
];
exports.FUZZ_TEST_EXPECTATIONS = {
performanceCheck: (executionTime_1, input_1, ...args_1) => __awaiter(void 0, [executionTime_1, input_1, ...args_1], void 0, function* (executionTime, input, targetExecutionTimeMs = 10000) {
if (executionTime >= targetExecutionTimeMs) {
throw new Error(`Input took too long (${executionTime}ms)! Expected time: ${targetExecutionTimeMs}ms. Input: "${input}"`);
}
}),
consoleErrorCheck: (errorLogs, input) => __awaiter(void 0, void 0, void 0, function* () {
if (errorLogs.length > 0) {
console.error(`Console error for input: "${input}" ->`, errorLogs);
}
expect(errorLogs).toEqual([]);
}),
xssAlertCheck: (browser, input) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield browser.driver.switchTo().alert();
throw new Error(`XSS detected! Alert triggered for input: "${input}"`);
}
catch (error) {
if (error.name !== "NoSuchAlertError") {
throw error;
}
}
}),
domManipulationCheck: (browser, input) => __awaiter(void 0, void 0, void 0, function* () {
const bodyHTML = yield browser.executeScript('return document.body.innerHTML;');
if (bodyHTML.includes('<script>')) {
console.error(`XSS in DOM! Input: "${input}"`);
console.log(bodyHTML);
}
expect(bodyHTML).not.toContain('<script>');
})
};
class UIComponent {
constructor(browser, locator, rootElement) {
this.browser = browser;
this.locator = locator;
this.rootElement = rootElement;
}
root() {
return __awaiter(this, void 0, void 0, function* () {
return (this.rootElement === undefined)
? yield this.browser.find(this.locator)
: yield this.browser.findChild(this.rootElement, this.locator);
});
}
findChild(selector_1) {
return __awaiter(this, arguments, void 0, function* (selector, { waitForChild = true, timeout = 10000, pollTimeout = 25 } = {}) {
const options = { waitForChild: waitForChild, timeout: timeout, pollTimeout: pollTimeout };
return yield this.browser.findChild(yield this.root(), selector, options);
});
}
findChildren(selector_1) {
return __awaiter(this, arguments, void 0, function* (selector, { waitForChild = true, timeout = 10000, pollTimeout = 25 } = {}) {
const options = { waitForChild: waitForChild, timeout: timeout, pollTimeout: pollTimeout };
return yield this.browser.findChildren(yield this.root(), selector, options);
});
}
waitUntilLoaded() {
return __awaiter(this, arguments, void 0, function* ({ timeout = 10000, pollTimeout = 50 } = {}) {
yield this.browser.wait(selenium_1.EC.isVisible(yield this.root()), {
timeout: timeout, pollTimeout: pollTimeout, message: 'Failed to load root component.'
});
const loading = '[class*=k-loading],[class*=k-i-loading],[class*=k-svg-i-loading]';
yield this.browser.wait(() => __awaiter(this, void 0, void 0, function* () { return (yield this.findChildren(loading, { waitForChild: false })).length === 0; }), {
timeout: timeout, pollTimeout: pollTimeout, message: 'Failed to load component.'
});
});
}
waitForAnimation() {
return __awaiter(this, arguments, void 0, function* ({ timeout = 10000, pollTimeout = 50 } = {}) {
yield this.browser.waitForAnimation(yield this.root(), { timeout: timeout, pollTimeout: pollTimeout });
});
}
/**
* Tests the component with various malicious inputs to ensure its robustness against common security vulnerabilities.
*
* @param {WebElement} [myInputElement] - The input element to be tested.
* @param {string[][]} [maliciousInputArray] - An array of arrays containing malicious input strings. If not provided, the method will use the default `MALICIOUS_INPUT_PAYLOADS`.
* @param {Partial<FuzzTestExpectations>} [expectationsArray] - An object containing custom expectations for the tests. If not provided, the method will use the default `FUZZ_TEST_EXPECTATIONS`.
*
* @example
* // Default usage
* await myComponent.setMaliciousInputs(myInputElement);
*
* @example
* // Partial customization of the expectations
* await myComponent.setMaliciousInputs(myInputElement, undefined, {
* performanceCheck: async (executionTime, input, targetExecutionTimeMs = 4000) => {
* if (executionTime >= targetExecutionTimeMs) {
* throw new Error(`Custom: Execution time exceeded for input: "${input}"`);
* }
* }
* });
*/
setMaliciousInputs(myInputElement_1) {
return __awaiter(this, arguments, void 0, function* (myInputElement, maliciousInputArray = exports.MALICIOUS_INPUT_PAYLOADS, expectationsArray = {}) {
// Merge custom expectations with defaults
const expectations = Object.assign(Object.assign({}, exports.FUZZ_TEST_EXPECTATIONS), expectationsArray // Custom overrides
);
for (const category of maliciousInputArray) {
console.log(`Testing category: ${category[0] || "Unnamed Category"}`);
for (const currentInput of category) {
console.log(`Testing input: "${currentInput}"`);
const startTime = Date.now();
yield this.browser.type(myInputElement, currentInput, { clear: true });
const executionTime = Date.now() - startTime;
if (expectations.performanceCheck) {
yield expectations.performanceCheck(executionTime, currentInput);
}
const errorLogs = yield this.browser.getErrorLogs([]);
if (expectations.consoleErrorCheck) {
yield expectations.consoleErrorCheck(errorLogs, currentInput);
}
if (expectations.xssAlertCheck) {
yield expectations.xssAlertCheck(this.browser, currentInput);
}
const inputValue = yield myInputElement.getAttribute('value');
if (expectations.sanitizationCheck) {
yield expectations.sanitizationCheck(inputValue, currentInput);
}
if (expectations.domManipulationCheck) {
yield expectations.domManipulationCheck(this.browser, currentInput);
}
}
}
});
}
}
exports.UIComponent = UIComponent;
//# sourceMappingURL=ui-component.js.map
;