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