UNPKG

@progress/kendo-e2e

Version:

Kendo UI end-to-end test utilities.

186 lines 9.26 kB
"use strict"; 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