UNPKG

flagpole

Version:

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

713 lines 24.7 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.Value = void 0; const util_1 = require("./util"); const assertion_result_1 = require("./logging/assertion-result"); const link_1 = require("./link"); const fs = require("fs"); const value_promise_1 = require("./value-promise"); const http_request_1 = require("./http/http-request"); const jpath_1 = require("./json/jpath"); class Value { constructor(_input, context, _name, _parent = null, _highlight = "") { this._input = _input; this.context = context; this._name = _name; this._parent = _parent; this._highlight = _highlight; this._sourceCode = null; } get $() { return this._input; } get tagName() { var _a; return ((_a = this._tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || ""; } get outerHTML() { return this._sourceCode || ""; } get is() { return this.assert().is; } selectOption(value) { throw "This Value does not support select."; } pressEnter() { throw "This Value does not support pressEnter."; } get length() { return new Value(this.$ && this.$["length"] ? this.$["length"] : 0, this.context, `Length of ${this._name}`); } get trim() { return new Value(typeof this.$ === "string" ? this.$.trim() : "", this.context, `Trim of ${this._name}`); } get uppercase() { return new Value(typeof this.$ === "string" ? this.$.toUpperCase() : "", this.context, `Uppercase of ${this._name}`); } get lowercase() { return new Value(typeof this.$ === "string" ? this.$.toLowerCase() : "", this.context, `Lowercase of ${this._name}`); } get first() { return new Value(util_1.firstIn(this.$), this.context, `First in ${this._name}`); } get mid() { return new Value(util_1.middleIn(this.$), this.context, `Middle in ${this._name}`); } get last() { return new Value(util_1.lastIn(this.$), this.context, `Last in ${this._name}`); } get random() { return new Value(util_1.randomIn(this.$), this.context, `Random in ${this._name}`); } get string() { return new Value(this.toString(), this.context, this.name); } get array() { return new Value(this.toArray(), this.context, this.name); } get float() { return new Value(this.toFloat(), this.context, this.name); } get int() { return new Value(this.toInteger(), this.context, this.name); } get bool() { return new Value(this.toBoolean(), this.context, this.name); } get json() { return new Value(this.toJSON(), this.context, this.name); } get path() { return this._path || ""; } get name() { return this._name || "it"; } get highlight() { return this._highlight; } get parent() { return this._parent; } get sourceCode() { return this._sourceCode === null ? "" : this._sourceCode; } get isFlagpoleValue() { return true; } rename(newName) { const oldName = this.name; this._name = newName; return this; } toArray() { return Array.isArray(this.$) ? this.$ : [this.$]; } valueOf() { return this.$; } toString() { const value = this._input; const type = util_1.toType(value); if (type == "value" && (value === null || value === void 0 ? void 0 : value.$)) { return String(value.$); } else if (value === null || value === void 0 ? void 0 : value.value) { return String(value.value); } else if (type == "object") { return String(Object.keys(value)); } return String(value); } toBoolean() { return !!this.$; } toFloat() { return parseFloat(this.toString()); } toInteger() { return parseInt(this.toString()); } toJSON() { try { return JSON.parse(this.toString()); } catch (ex) { return null; } } toURL(baseUrl) { return new URL(this.toString(), baseUrl); } toType() { return String(util_1.toType(this._input)); } isNullOrUndefined() { return util_1.isNullOrUndefined(this._input); } isUndefined() { return this.toType() == "undefined"; } isNull() { return this._input === null; } isPromise() { return this.toType() == "promise"; } isArray() { return this.toType() == "array"; } isString() { return this.toType() == "string"; } isObject() { return this.toType() == "object"; } isNumber() { return this.toType() == "number" && this._input !== NaN; } isNumeric() { return !isNaN(this.$); } isNaN() { return this.$ === NaN; } isCookie() { return this._input && this.$["cookieString"]; } isRegularExpression() { return this.toType() == "regexp"; } isCheerioElement() { return this.toType() == "cheerio"; } isPuppeteerElement() { return this.toType() == "elementhandle"; } hasProperty(key, value) { return __awaiter(this, void 0, void 0, function* () { const thisValue = yield this.getProperty(key); if (value === undefined) { return !thisValue.isNullOrUndefined(); } if (value instanceof RegExp) { return value.test(thisValue.toString()); } return value == thisValue.$; }); } hasValue(value) { return __awaiter(this, void 0, void 0, function* () { const thisValue = yield this.getValue(); if (value === undefined) { return !thisValue.isNullOrUndefined(); } if (value instanceof RegExp) { return value.test(thisValue.toString()); } return value == thisValue.$; }); } getProperty(key) { return value_promise_1.ValuePromise.execute(() => __awaiter(this, void 0, void 0, function* () { return this._wrapAsValue(this._input[key], `${this.name} property of ${key}`); })); } click(opts) { this.context.logFailure(`Element could not be clicked on: ${this.name}`); return value_promise_1.ValuePromise.wrap(this); } submit() { this.context.logFailure(`Element could not be submitted on: ${this.name}`); return value_promise_1.ValuePromise.wrap(this); } open(a, type) { const scenario = typeof a == "string" ? this.context.suite.scenario(a, type || this.context.scenario.type) : a; util_1.runAsync(() => __awaiter(this, void 0, void 0, function* () { const link = yield this.getLink(); if (link.isNavigation()) { scenario.open(link.getUri()); } })); this._completedAction("OPEN"); return scenario; } isVisible() { return __awaiter(this, void 0, void 0, function* () { return true; }); } isHidden() { return __awaiter(this, void 0, void 0, function* () { return false; }); } isTag(...tagNames) { if (!this.tagName) { return false; } return tagNames.length ? tagNames.includes(this.tagName) : true; } getLink() { return __awaiter(this, void 0, void 0, function* () { const src = yield this.getUrl(); return new link_1.Link(src.isString() ? src.toString() : "", this.context.scenario.buildUrl()); }); } getUrl() { return value_promise_1.ValuePromise.execute(() => __awaiter(this, void 0, void 0, function* () { const url = yield (() => __awaiter(this, void 0, void 0, function* () { if (this.isString()) { return this.toString(); } if (this.isTag("img", "script", "video", "audio", "object", "iframe", "source")) { return (yield this.getAttribute("src")).$; } else if (this.isTag("a", "link")) { return (yield this.getAttribute("href")).$; } else if (this.isTag("form")) { return ((yield this.getAttribute("action")).$ || this.context.scenario.url); } return null; }))(); return this._wrapAsValue(url, `URL from ${this.name}`, this); })); } fillForm(a, b) { return value_promise_1.ValuePromise.wrap(this); } exists(selector) { return value_promise_1.ValuePromise.execute(() => __awaiter(this, void 0, void 0, function* () { if (selector === undefined) { this.isNullOrUndefined() ? this._failedAction("EXISTS", `${this.name}`) : this._completedAction("EXISTS", `${this.name}`); return this; } else { const el = yield this.find(selector); el.isNull() ? this._failedAction("EXISTS", `${selector}`) : this._completedAction("EXISTS", `${selector}`); return el; } })); } find(selector) { return value_promise_1.ValuePromise.wrap(this.item(selector)); } findAll(selector) { return __awaiter(this, void 0, void 0, function* () { return [yield this.find(selector)]; }); } getClassName() { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(null, `${this.name} Class`)); } hasClassName(name) { return __awaiter(this, void 0, void 0, function* () { const myClass = (yield this.getClassName()).toString(); const classes = myClass.split(" "); return (() => { if (name === undefined) { return !!myClass; } return classes.some((cls) => { return typeof name == "string" ? name == cls : name.test(cls); }); })(); }); } getTag() { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(this.tagName, `Tag Name of ${this.name}`)); } hasTag(tag) { return __awaiter(this, void 0, void 0, function* () { const myTag = (yield this.getTag()).$; if (tag === undefined) { return !!myTag; } return tag instanceof RegExp ? tag.test(myTag) : myTag == tag; }); } getInnerText() { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(this.toString(), `Inner Text of ${this.name}`)); } getInnerHtml() { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(null, `Inner HTML of ${this.name}`)); } getOuterHtml() { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(null, `Outer HTML of ${this.name}`)); } hasAttribute(key, value) { return __awaiter(this, void 0, void 0, function* () { const thisValue = yield this.getAttribute(key); if (thisValue.isNullOrUndefined()) { return false; } const strThisValue = thisValue.toString(); return value === undefined ? !!thisValue : typeof value == "string" ? value == strThisValue : value.test(strThisValue); }); } getAttribute(key) { return this.getProperty(key); } getStyleProperty(key) { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(null, `Style of ${key}`)); } getValue() { return value_promise_1.ValuePromise.wrap(this); } scrollTo() { return value_promise_1.ValuePromise.wrap(this); } hasText(text) { return __awaiter(this, void 0, void 0, function* () { const myText = (yield this.getText()).$; return text ? text == myText : !!myText; }); } getText() { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(this.toString(), this.name, this.parent, this.highlight)); } get values() { let values = []; try { values = Object.values(this.$); } catch (_a) { } return this._wrapAsValue(values, `Values of ${this.name}`, this, this.highlight); } get keys() { let keys = []; try { keys = Object.keys(this.$); } catch (_a) { } return this._wrapAsValue(keys, `Keys of ${this.name}`, this, this.highlight); } screenshot() { return __awaiter(this, void 0, void 0, function* () { throw new Error(`This value type (${this.toType()}) or scenario type does not support screenshots.`); }); } eval(js) { return __awaiter(this, void 0, void 0, function* () { throw `This element does not support eval().`; }); } focus() { throw `This element does not support focus().`; } hover() { throw `This element does not support hover().`; } blur() { throw `This element does not support blur().`; } tap(opts) { throw `This element does not support tap().`; } longpress(opts) { throw `This element does not support longpress().`; } press(key, opts) { throw `This element does not support press().`; } clearThenType(textToType, opts) { throw `This element does not support clearThenType().`; } type(textToType, opts) { throw `This element does not support type().`; } clear() { throw `This element does not support clear().`; } getAncestor(selector) { throw `getAncestor() is not supported by ${this.name}`; } getChildren(selector) { return __awaiter(this, void 0, void 0, function* () { throw `getChildren() is not supported by ${this.name}`; }); } getAncestors(selector) { return __awaiter(this, void 0, void 0, function* () { throw `getAncestors() is not supported by ${this.name}`; }); } getAncestorOrSelf(selector) { throw `getAncestorOrSelf() is not supported by ${this.name}`; } getFirstChild(selector) { throw `getFirstChild() is not supported by ${this.name}`; } getLastChild(selector) { throw `getLastChild() is not supported by ${this.name}`; } getFirstSibling(selector) { throw `getFirstSibling() is not supported by ${this.name}`; } getLastSibling(selector) { throw `getLastSibling() is not supported by ${this.name}`; } getChildOrSelf(selector) { throw `getChildOrSelf() is not supported by ${this.name}`; } getDescendantOrSelf(selector) { throw `getDescendantOrSelf() is not supported by ${this.name}`; } getDescendants(selector) { return __awaiter(this, void 0, void 0, function* () { throw `getDescendants() is not supported by ${this.name}`; }); } getParent() { throw `getParent() is not supported by ${this.name}`; } getSiblings(selector) { return __awaiter(this, void 0, void 0, function* () { throw `getSiblings() is not supported by ${this.name}`; }); } getPreviousSibling(selector) { throw `getPreviousSibling() is not supported by ${this.name}`; } getPreviousSiblings(selector) { return __awaiter(this, void 0, void 0, function* () { throw `getPreviousSiblings() is not supported by ${this.name}`; }); } getNextSibling(selector) { throw `getNextSibling() is not supported by ${this.name}`; } getNextSiblings(selector) { return __awaiter(this, void 0, void 0, function* () { throw `getNextSiblings() is not supported by ${this.name}`; }); } getBounds(boxType) { return __awaiter(this, void 0, void 0, function* () { return null; }); } download(a, b) { return __awaiter(this, void 0, void 0, function* () { const link = yield this.getLink(); if (!link.isNavigation()) { return null; } const localFilePath = typeof a == "string" ? a : null; const opts = (() => { if (typeof a == "object" && a !== null) { return a; } if (typeof b == "object" && b !== null) { return b; } return { encoding: "utf8" }; })(); const request = new http_request_1.HttpRequest(Object.assign({ uri: link.getUri(), method: "get", }, opts)); const resp = yield request.fetch(); const file = resp.headers["content-type"].startsWith("image") ? Buffer.from(resp.body, "base64") : resp.body; if (localFilePath) { fs.writeFileSync(localFilePath, file); } return resp; }); } waitForFunction(js) { throw `waitForFunction() is not supported by this type of scenario`; } waitForHidden() { throw `waitForHidden() is not supported by this type of scenario`; } waitForVisible() { throw `waitForVisible() is not supported by this type of scenario`; } setValue(text) { throw `setValue() is not supported by ${this.name}`; } assert(message) { return typeof message == "string" ? this.context.assert(message, this) : this.context.assert(this); } split(by, limit) { return new Value(this.toString().split(by, limit), this.context, this.name); } join(by) { return new Value(this.toArray().join(by), this.context, this.name); } pluck(property) { const arr = this.toArray().map((item) => item[property]); return new Value(arr, this.context, `Values of ${property} in ${this.name}`); } nth(index) { const value = util_1.nthIn(this.$, index); const nth = util_1.toOrdinal(index + 1); return new Value(value, this.context, `${nth} value in ${this.name}`); } map(callback) { return new Value(this.isArray() ? this.toArray().map(callback) : callback(this._input), this.context, this.name); } filter(func) { return new Value(this.toArray().filter(func), this.context, this.name); } each(callback) { this.toArray().forEach(callback); return this; } min(key) { return new Value(this.toArray().reduce((min, row) => { const val = key ? row[key] : row; return min === null || val < min ? val : min; }, null), this.context, this.name); } max(key) { return new Value(this.toArray().reduce((max, row) => { const val = key ? row[key] : row; return max === null || val > max ? val : max; }, null), this.context, this.name); } sum(key) { return new Value(Number(this.toArray().reduce((sum, row) => (sum += Number(key ? row[key] : row)), 0)), this.context, this.name); } count(key) { return new Value(Number(this.toArray().reduce((count, row) => { if (key) { return count + !!row[key] ? 1 : 0; } return count + 1; }, 0)), this.context, this.name); } unique() { return new Value([...new Set(this.toArray())], this.context, this.name); } groupBy(key) { return new Value(this.toArray().reduce((grouper, row) => { const val = String(row[key]); if (!grouper[val]) { grouper[val] = []; } grouper[val].push(row); return grouper; }, {}), this.context, this.name); } asc(key) { const collator = new Intl.Collator("en", { numeric: true, sensitivity: "base", }); const arr = this.toArray().sort((a, b) => key ? collator.compare(a[key], b[key]) : collator.compare(a, b)); return new Value(arr, this.context, this.name); } desc(key) { const collator = new Intl.Collator("en", { numeric: true, sensitivity: "base", }); const arr = this.toArray().sort((a, b) => (key ? collator.compare(a[key], b[key]) : collator.compare(a, b)) * -1); return new Value(arr, this.context, this.name); } median(key) { const arr = this.toArray().sort((a, b) => key ? parseFloat(a[key]) - parseFloat(b[key]) : a - b); const med = Number(arr[Math.floor(arr.length / 2)]); return new Value(med, this.context, this.name); } avg(key) { const arr = this.toArray(); return new Value(arr.reduce((sum, row) => (sum += Number(key ? row[key] : row)), 0) / arr.length, this.context, this.name); } reduce(callback, initial) { return new Value(this.toArray().reduce(callback, initial), this.context, this.name); } every(callback) { return new Value(this.toArray().every(callback), this.context, this.name); } some(callback) { return new Value(this.toArray().some(callback), this.context, this.name); } none(callback) { return new Value(!this.toArray().some(callback), this.context, this.name); } item(key) { const name = `${key} in ${this.name}`; if (typeof key === "string") { return new Value(jpath_1.jpathSearch(this.$, key), this.context, name); } if (this.$[key]) { return new Value(this.$[key], this.context, name); } return new Value(null, this.context, name); } echo(callback) { this.context.comment(callback ? callback(this.toString()) : this.toString()); return this; } col(key) { if (Array.isArray(key)) { const name = `${key.join(", ")} in ${this.name}`; return new Value(this.toArray().map((row) => { const out = []; key.forEach((k) => { out.push(row[k]); }); return out; }), this.context, name); } const name = `${key} in ${this.name}`; return new Value(this.toArray().map((row) => row[key]), this.context, name); } gesture(type, opts) { throw `gesture not implemented for ${this.name}`; } _completedAction(verb, noun) { return __awaiter(this, void 0, void 0, function* () { this.context.scenario.result(new assertion_result_1.AssertionActionCompleted(verb, noun || this.name)); }); } _failedAction(verb, noun) { return __awaiter(this, void 0, void 0, function* () { this.context.scenario.result(new assertion_result_1.AssertionActionFailed(verb, noun || this.name)); }); } _wrapAsValue(data, name, parent, highlight) { const val = new Value(data, this.context, name, parent, highlight); if (!val.sourceCode && parent && parent.sourceCode) { val._sourceCode = parent.sourceCode; } return val; } _wrapAsValuePromise(data, name, parent, highlight) { return value_promise_1.ValuePromise.wrap(this._wrapAsValue(data, name, parent, highlight)); } } exports.Value = Value; //# sourceMappingURL=value.js.map