flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
524 lines • 23.5 kB
JavaScript
"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