flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
186 lines • 7.16 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.BrowserControl = void 0;
const puppeteer = require("puppeteer-core");
const httprequest_1 = require("./httprequest");
class BrowserControl {
constructor() {
this._request = new httprequest_1.HttpRequest({});
this._browser = null;
this._page = null;
this._response = null;
this._consoleMessages = [];
this._puppeteer = null;
}
get consoleMessages() {
return this._consoleMessages;
}
get response() {
return this._response;
}
get page() {
return this._page;
}
get browser() {
return this._browser;
}
get puppeteer() {
return this._puppeteer;
}
get request() {
return this._request;
}
get browserOpts() {
return this._request.browser;
}
get _dynamicPuppeteer() {
if (!this._puppeteer) {
return (Promise.resolve().then(() => require("puppeteer")).then((newPuppeteer) => {
this._puppeteer = newPuppeteer;
return this._puppeteer;
})
.catch((e) => {
this._puppeteer = puppeteer;
return this._puppeteer;
}));
}
return Promise.resolve(this._puppeteer);
}
_getCookies() {
return __awaiter(this, void 0, void 0, function* () {
if (this._page === null) {
throw new Error("Page is null");
}
const puppeteerCookies = yield this._page.cookies();
const cookies = {};
puppeteerCookies.forEach((puppeteerCookie) => {
cookies[puppeteerCookie.name] = puppeteerCookie.value;
});
return cookies;
});
}
close() {
return __awaiter(this, void 0, void 0, function* () {
if (this._page !== null) {
yield this._page.close();
}
});
}
has404() {
return this._find404Errors().length > 0;
}
open(request) {
this._request = request;
if (typeof this.request.uri == "undefined") {
throw new Error("Must have a URL to load.");
}
return new Promise((resolve, reject) => {
this._dynamicPuppeteer.then((puppeteer) => __awaiter(this, void 0, void 0, function* () {
this.browserOpts.defaultViewport =
this.browserOpts.defaultViewport || {};
this.browserOpts.defaultViewport.width =
this.browserOpts.defaultViewport.width ||
this.browserOpts.width ||
800;
this.browserOpts.defaultViewport.height =
this.browserOpts.defaultViewport.height ||
this.browserOpts.width ||
600;
this.browserOpts.args = this.browserOpts.args || [];
this.browserOpts.args.push("--no-sandbox");
this.browserOpts.args.push("--disable-setuid-sandbox");
this._browser = yield puppeteer.launch(this.browserOpts);
this._page = yield this._onBrowserReady(this._browser);
this._recordConsoleOutput();
Promise.all([this._applyCookies(), this._setBasicAuth()])
.then(() => __awaiter(this, void 0, void 0, function* () {
resolve({
response: yield this._openUri(),
body: this._page ? yield this._page.content() : "",
cookies: yield this._getCookies(),
});
}))
.catch(reject);
}));
});
}
_onBrowserReady(browser) {
return __awaiter(this, void 0, void 0, function* () {
const pages = yield browser.pages();
return pages.length > 0 ? pages[0] : yield browser.newPage();
});
}
_recordConsoleOutput() {
if (this.browserOpts.recordConsole && this._page !== null) {
this._page.on("console", (consoleMesssage) => {
if (this.browserOpts.outputConsole) {
console.log(`Console: ${consoleMesssage
.type()
.toUpperCase()} - ${consoleMesssage.text()}`);
}
this._consoleMessages.push({
type: consoleMesssage.type(),
text: consoleMesssage.text(),
source: consoleMesssage,
});
});
}
}
_setBasicAuth() {
return __awaiter(this, void 0, void 0, function* () {
if (this._page !== null && this.request.auth) {
return this._page.authenticate(this.request.auth);
}
});
}
_applyCookies() {
return __awaiter(this, void 0, void 0, function* () {
if (Object.values(this.request.cookies).length && this._page) {
const tld = this._request.uri
? new URL(this._request.uri).hostname.split(".").slice(-2).join(".")
: undefined;
const puppeteerCookies = Object.keys(this.request.cookies).map((key) => {
return {
name: key,
value: this.request.cookies[key],
domain: `.${tld}`,
};
});
return this._page.setCookie(...puppeteerCookies);
}
});
}
_openUri() {
return __awaiter(this, void 0, void 0, function* () {
if (this._page === null) {
throw new Error("Page is null.");
}
const response = yield this._page.goto(this.request.uri || "/", {
timeout: 30000,
waitUntil: "networkidle2",
});
if (response === null) {
throw new Error("Browser response is null.");
}
this._response = response;
return response;
});
}
_find404Errors() {
return this._consoleMessages.filter((consoleMessage) => {
const text = consoleMessage.text;
return text.indexOf("404 (Not Found)") > -1;
});
}
}
exports.BrowserControl = BrowserControl;
//# sourceMappingURL=browsercontrol.js.map