UNPKG

flagpole

Version:

Simple and fast DOM integration, headless or headful browser, and REST API testing framework.

524 lines 23.5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const value_1 = require("./value"); const link_1 = require("./link"); const response_1 = require("./response"); const _1 = require("."); class DOMElement extends value_1.ProtoValue { get path() { return this._path; } get name() { return this._name || this._path || 'DOM Element'; } static create(input, context, name = null, path) { return __awaiter(this, void 0, void 0, function* () { const element = new DOMElement(input, context, name, path); if (name === null) { const tagName = yield element._getTagName(); if (tagName !== null) { element._name = `<${tagName}> Element @ ${path}`; } else if (path) { element._name = String(path); } } return element; }); } constructor(input, context, name, path) { super(input, context, (name || 'DOM Element')); this._path = path || ''; } toString() { if (this.isCheerioElement()) { return this._context.response.getRoot().html(this._input); } else if (this.isPuppeteerElement()) { return String(this.path); } return ''; } getClassName() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement()) { return this._wrapAsValue((typeof this._input.get(0).attribs['class'] !== 'undefined') ? this._input.get(0).attribs['class'] : null, `Class Name of ${this.name}`); } else if (this.isPuppeteerElement()) { const classHandle = yield this._input.getProperty('className'); return this._wrapAsValue(yield classHandle.jsonValue(), `Class Name of ${this.name}`); } throw new Error(`getClassName is not supported with ${this.toType()}.`); }); } hasClassName(className) { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement()) { return this._wrapAsValue(this._input.hasClass(className), `${this.name} has class ${className}`); } else if (this.isPuppeteerElement()) { const classHandle = yield this._input.getProperty('className'); const classString = yield classHandle.jsonValue(); return this._wrapAsValue((classString.split(' ').indexOf(className) >= 0), `${this.name} has class ${className}`); } throw new Error(`hasClassName is not supported with ${this.toType()}.`); }); } getTagName() { return __awaiter(this, void 0, void 0, function* () { const tagName = yield this._getTagName(); return this._wrapAsValue(tagName, `Tag Name of ${this.name}`); }); } getInnerText() { return __awaiter(this, void 0, void 0, function* () { if (this.isPuppeteerElement() && this._context.page !== null) { return this._wrapAsValue(yield this._context.page.evaluate(e => e.innerText, this.$), `Inner Text of ${this.name}`); } else if (this.isCheerioElement()) { return this._wrapAsValue(this._input.text(), `Inner Text of ${this.name}`); } throw new Error(`getInnerText is not supported with ${this.toType()}.`); }); } getInnerHtml() { return __awaiter(this, void 0, void 0, function* () { if (this.isPuppeteerElement() && this._context.page !== null) { return this._wrapAsValue(yield this._context.page.evaluate(e => e.innerHTML, this.$), `Inner Html of ${this.name}`); } else if (this.isCheerioElement()) { return this._wrapAsValue(this._input.html(), `Inner Html of ${this.name}`); } throw new Error(`getInnerHtml is not supported with ${this.toType()}.`); }); } getOuterHtml() { return __awaiter(this, void 0, void 0, function* () { if (this.isPuppeteerElement() && this._context.page !== null) { return this._wrapAsValue(yield this._context.page.evaluate(e => e.outerHTML, this.$), `Outer Html of ${this.name}`); } else if (this.isCheerioElement()) { return this._wrapAsValue(this._context.response.getRoot().html(this._input), `Outer Html of ${this.name}`); } throw new Error(`getInnerHtml is not supported with ${this.toType()}.`); }); } hasAttribute(key) { return __awaiter(this, void 0, void 0, function* () { return this._wrapAsValue((yield this._getAttribute(key)) != null, `${this.name} has attribute ${key}`); }); } getAttribute(key) { return __awaiter(this, void 0, void 0, function* () { const name = `${this.name} -> ${key}`; const attr = yield this._getAttribute(key); return this._wrapAsValue(attr, name); }); } hasProperty(key) { return __awaiter(this, void 0, void 0, function* () { return this._wrapAsValue(!(yield this.getProperty(key)).isNull(), `Does ${this.name} have property ${key}?`); }); } getProperty(key) { return __awaiter(this, void 0, void 0, function* () { const name = `${this.name} -> ${key}`; if (this.isCheerioElement()) { return this._wrapAsValue(this._input.prop(key), name); } else if (this.isPuppeteerElement()) { const handle = yield this._input.getProperty(key); return this._wrapAsValue(yield handle.jsonValue(), name); } throw new Error(`getProperty is not supported with ${this.toType()}.`); }); } hasData(key) { return __awaiter(this, void 0, void 0, function* () { return this._wrapAsValue(!(yield this.getData(key)).isNull(), `${this.name} has data ${key}`); }); } getData(key) { return __awaiter(this, void 0, void 0, function* () { const name = `${this.name} -> ${key}`; if (this.isCheerioElement()) { return this._wrapAsValue(this._input.data(key), name); } else if (this.isPuppeteerElement()) { const handle = yield this._input.getProperty(key); return this._wrapAsValue(yield handle.jsonValue(), name); } throw new Error(`getData is not supported with ${this.toType()}.`); }); } getValue() { return __awaiter(this, void 0, void 0, function* () { const name = `Value of ${this.name}`; if (this.isCheerioElement()) { return this._wrapAsValue(this._input.val(), name); } else if (this.isPuppeteerElement()) { const handle = yield this._input.getProperty('value'); return this._wrapAsValue(yield handle.jsonValue(), name); } throw new Error(`getValue is not supported with ${this.toType()}.`); }); } getText() { return __awaiter(this, void 0, void 0, function* () { const name = `Text of ${this.name}`; if (this.isCheerioElement()) { return this._wrapAsValue(this._input.text(), name); } else if (this.isPuppeteerElement()) { const handle = yield this._input.getProperty('textContent'); return this._wrapAsValue(yield handle.jsonValue(), name); } throw new Error(`getText is not supported with ${this.toType()}.`); }); } fillForm(formData) { return __awaiter(this, void 0, void 0, function* () { const element = this; const isForm = yield this._isFormTag(); if (isForm) { if (element.isCheerioElement()) { const form = element._input; for (let name in formData) { const value = formData[name]; form.find(`[name="${name}"]`).val(value); } } else if (element.isPuppeteerElement()) { const page = element._context.page; if (page !== null) { for (let name in formData) { const value = formData[name]; const selector = `${element._path} [name="${name}"]`; const inputs = yield page.$$(selector); if (inputs.length > 0) { const input = inputs[0]; const tagName = (yield (yield input.getProperty('tagName')).jsonValue()).toLowerCase(); const inputType = (yield (yield input.getProperty('type')).jsonValue()).toLowerCase(); yield page.focus(selector); if (tagName == 'select') { yield page.select(selector, value); } else if (tagName == 'input') { if (inputType == 'radio' || inputType == 'checkbox') { const multiValues = _1.Flagpole.toType(value) == 'array' ? value : [value]; for (let i = 0; i < inputs.length; i++) { let checkbox = inputs[i]; let isChecked = !!(yield (yield checkbox.getProperty('checked')).jsonValue()); let checkboxValue = String(yield (yield checkbox.getProperty('value')).jsonValue()); if ((multiValues.indexOf(checkboxValue) >= 0 && !isChecked) || (multiValues.indexOf(checkboxValue) < 0 && isChecked)) { yield checkbox.click(); } } } else if (inputType == 'button' || inputType == 'submit' || inputType == 'reset') { } else { yield this._context.clearThenType(selector, value); } } else if (tagName == 'button') { } } } } } return element; } else { throw new Error('This is not a form element.'); } }); } submit(a, b) { return __awaiter(this, void 0, void 0, function* () { if (!this._isFormTag()) { throw new Error('You can only use .submit() with a form element.'); } if (this.isPuppeteerElement()) { if (this._context.page === null) { throw new Error('Page was null'); } return yield this._context.page.evaluate(form => form.submit(), this.$); } else if (this.isCheerioElement()) { const link = yield this._getLink(); const scenario = yield this._createLambdaScenario(a, b); const method = ((yield this._getAttribute('method')) || 'get').toString().toLowerCase(); if (link.isNavigation()) { let uri; scenario.setMethod(method); if (method == 'get') { uri = link.getUri(this.$.serializeArray()); } else { const formDataArray = this.$.serializeArray(); const formData = {}; uri = link.getUri(); formDataArray.forEach(function (input) { formData[input.name] = input.value; }); scenario.setFormData(formData); } return yield scenario.open(uri); } else { return scenario.skip('Nothing to submit'); } } throw new Error('This is not supported yet.'); }); } click(a, b) { return __awaiter(this, void 0, void 0, function* () { const callback = (() => { if (typeof b == 'function') { return b; } else if (typeof a == 'function') { return a; } return function () { }; })(); const message = typeof a == 'string' ? a : ''; if (this.isPuppeteerElement()) { message && this._context.scenario.comment(message); return yield this._input.click(); } if (yield this._isLinkTag()) { return yield this.load(message, callback); } if (yield this._isButtonTag()) { const type = (yield this.getAttribute('type')); if (type.isNull() || type.toString().toLowerCase() == 'submit') { const form = this._input.closest('form'); const formEl = yield DOMElement.create(form, this._context, `Parent form of ${this.name}`, this.path); return yield formEl.submit(message, callback); } throw Error('This button did not have any action to submit.'); } throw Error('This is not a clickable element.'); }); } load(a, b) { return __awaiter(this, void 0, void 0, function* () { const link = yield this._getLink(); const scenario = yield this._createLambdaScenario(a, b); if (link.isNavigation()) { scenario.title = (typeof a == 'string' && a.length) ? a : `Load ${link.getUri()}`; setTimeout(() => { scenario.open(link.getUri()); }, 1); } else { scenario.skip('Not a navigational link'); } return scenario; }); } _isFormTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { return (yield this._getTagName()) == 'form'; } return false; }); } _isButtonTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { const tagName = yield this._getTagName(); const type = yield this._getAttribute('type'); return (tagName === 'button' || (tagName === 'input' && (['button', 'submit', 'reset'].indexOf(String(type)) >= 0))); } return false; }); } _isLinkTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { return ((yield this._getTagName()) === 'a' && (yield this._getAttribute('href')) !== null); } return false; }); } _isImageTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { return ((yield this._getTagName()) === 'img' && (yield this._getAttribute('src')) !== null); } return false; }); } _isVideoTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { const tagName = yield this._getTagName(); const src = yield this._getAttribute('src'); const type = yield this._getAttribute('type'); return ((tagName === 'video' && src !== null) || (tagName === 'source' && src !== null && /video/i.test(type || ''))); } return false; }); } _isAudioTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { const tagName = yield this._getTagName(); const src = yield this._getAttribute('src'); const type = yield this._getAttribute('type'); return ((tagName === 'audio' && src !== null) || (tagName === 'bgsound' && src !== null) || (tagName === 'source' && src !== null && /audio/i.test(type || ''))); } return false; }); } _isScriptTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { return ((yield this._getTagName()) === 'script' && (yield this._getAttribute('src')) !== null); } return false; }); } _isStylesheetTag() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement() || this.isPuppeteerElement()) { return ((yield this._getTagName()) === 'link' && (yield this._getAttribute('href')) !== null && String(yield this._getAttribute('rel')).toLowerCase() == 'stylesheet'); } return false; }); } _isClickable() { return __awaiter(this, void 0, void 0, function* () { return ((yield this._isLinkTag()) || (yield this._isButtonTag())); }); } _getUrl() { return __awaiter(this, void 0, void 0, function* () { const tagName = yield this._getTagName(); if (this.isCheerioElement() || this.isPuppeteerElement()) { if (tagName !== null) { if (['img', 'script', 'video', 'audio', 'object', 'iframe'].indexOf(tagName) >= 0) { return this._getAttribute('src'); } else if (['a', 'link'].indexOf(tagName) >= 0) { return this._getAttribute('href'); } else if (['form'].indexOf(tagName) >= 0) { return this._getAttribute('action') || this._context.scenario.url; } else if (['source'].indexOf(tagName) >= 0) { return this._getAttribute('src'); } } } return null; }); } _getLambdaScenarioType() { return __awaiter(this, void 0, void 0, function* () { if ((yield this._isFormTag()) || (yield this._isClickable())) { return (this._context.scenario.responseType == response_1.ResponseType.browser) ? response_1.ResponseType.browser : response_1.ResponseType.html; } else if (yield this._isImageTag()) { return response_1.ResponseType.image; } else if (yield this._isStylesheetTag()) { return response_1.ResponseType.stylesheet; } else if (yield this._isScriptTag()) { return response_1.ResponseType.script; } else if (yield this._isVideoTag()) { return response_1.ResponseType.video; } else { return response_1.ResponseType.resource; } }); } _getLink() { return __awaiter(this, void 0, void 0, function* () { const srcPath = yield this._getUrl(); return new link_1.Link(srcPath || '', this._context); }); } _createLambdaScenario(a, b) { return __awaiter(this, void 0, void 0, function* () { const title = typeof a == 'string' ? a : this._path; const scenarioType = yield this._getLambdaScenarioType(); const newScenarioIsBrowser = (scenarioType == response_1.ResponseType.browser || scenarioType == response_1.ResponseType.extjs); const curScenarioIsBrowser = (this._context.scenario.responseType == response_1.ResponseType.browser || this._context.scenario.responseType == response_1.ResponseType.extjs); const opts = ((newScenarioIsBrowser && curScenarioIsBrowser) || !newScenarioIsBrowser) ? this._context.scenario.requestOptions : {}; const scenario = this._context.suite.scenario(title, scenarioType, opts); scenario.next((function () { if (typeof b == 'function') { return b; } else if (typeof a == 'function') { return a; } else { return function () { }; } })()); return scenario; }); } _getTagName() { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement()) { return this._input.get(0).tagName.toLowerCase(); } else if (this.isPuppeteerElement()) { const handle = yield this._input.getProperty('tagName'); return String(yield handle.jsonValue()).toLowerCase(); } throw new Error(`getTagName is not supported with ${this.toType()}.`); }); } _getAttribute(key) { return __awaiter(this, void 0, void 0, function* () { if (this.isCheerioElement()) { return (typeof this._input.get(0).attribs[key] !== 'undefined') ? this._input.get(0).attribs[key] : null; } else if (this.isPuppeteerElement()) { const handle = yield this._input.getProperty(key); return yield handle.jsonValue(); } throw new Error(`getAttribute is not supported with ${this.toType()}.`); }); } } exports.DOMElement = DOMElement; //# sourceMappingURL=domelement.js.map