flagpole
Version:
Simple and fast DOM integration and REST API testing framework.
233 lines (201 loc) • 5.83 kB
text/typescript
import { Scenario } from "./scenario";
import { iResponse, SimplifiedResponse } from "./response";
import { Node } from "./node";
import { URL } from 'url';
/**
* Responses may be HTML or JSON, so this interface let's us know how to handle either
*/
export interface iResponse {
getType(): ResponseType
select(path: string, findIn?: any): Node
status(): Node
and(): Node
loadTime(): Node
headers(key?: string): Node
label(message: string): iResponse
setLastElement(path: string | null, element: Node): Node
getLastElement(): Node
getLastElementPath(): string | null
getRoot(): any
getBody(): string
getUrl(): string
comment(message: string): iResponse
not(): iResponse
optional(): iResponse
ignore(assertions?: boolean | Function): iResponse
assert(statement: boolean, message: string, actualValue?: string): iResponse
absolutizeUri(uri: string): string
readonly scenario: Scenario
}
export enum ResponseType {
html,
json,
image,
stylesheet,
script,
resource
}
/**
* This is named confusing, but it represents the original response we get from the http request
*/
export interface SimplifiedResponse {
statusCode: number
body: string
headers: any
}
export abstract class GenericResponse implements iResponse {
public readonly scenario: Scenario;
private _url: string;
private _statusCode: number;
private _body: string;
private _headers: {};
private _lastElement: Node;
private _lastElementPath: string | null = null;
abstract getType(): ResponseType;
abstract select(path: string, findIn?: any): Node;
constructor(scenario: Scenario, url: string, simplifiedResponse: SimplifiedResponse) {
this.scenario = scenario;
this._url = url;
this._statusCode = simplifiedResponse.statusCode;
this._body = simplifiedResponse.body;
this._headers = simplifiedResponse.headers;
this._lastElement = new Node(this, 'Empty Element', null);
}
public absolutizeUri(uri: string): string {
let baseUrl: URL = new URL(this.scenario.suite.buildUrl(this.scenario.getUrl() || ''));
return (new URL(uri, baseUrl.href)).href;
}
public getUrl(): string {
return this._url;
}
public body(): Node {
return new Node(this, 'Response Body', this._body);
}
public getBody(): string {
return this._body;
}
public getRoot(): any {
return this._body;
}
public assert(statement: boolean, message: string, actualValue?: string): iResponse {
this.scenario.assert(statement, message, actualValue);
return this;
}
public not(): iResponse {
this.scenario.not();
return this;
}
public optional(): iResponse {
this.scenario.optional();
return this;
}
public ignore(assertions: boolean | Function = true): iResponse {
this.scenario.ignore(assertions);
return this;
}
/**
* Set human readable label to override normal assertion message for next test
*
* @param {string} message
* @returns {iResponse}
*/
public label(message: string): iResponse {
this.scenario.label(message);
return this;
}
/**
* Add a console comment
*
* @param {string} message
* @returns {iResponse}
*/
public comment(message: string): iResponse {
this.scenario.comment(message);
return this;
}
/**
* Set last element
*
* @param path
* @param element
*/
public setLastElement(path: string | null, element: Node): Node {
this._lastElement = element;
this._lastElementPath = path;
return element;
}
/**
* Get or set last element
*
* @param {Node} property
* @returns {Node}
*/
public getLastElement(): Node {
return this._lastElement || new Node(this, 'Empty Element', []);
}
/**
* Last selected/traversed path
*/
public getLastElementPath(): string | null {
return this._lastElementPath;
}
/**
* Return last element
*
* @returns {Node}
*/
public and(): Node {
return this.getLastElement();
}
/**
* Return a single header by key or all headers in an object
*
* @param {string} key
* @returns {Node}
*/
public headers(key?: string): Node {
if (typeof key !== 'undefined') {
// Try first as they put it in the test, then try all lowercase
key = typeof this._headers[key] !== 'undefined' ? key : key.toLowerCase();
let name: string = 'HTTP Headers[' + key + ']';
let value: Node = new Node(this, name, this._headers[key]);
value.exists();
return value;
}
else {
return new Node(this, 'HTTP Headers', this._headers);
}
}
/**
* Get the http status
*
* @returns {Node}
*/
public status(): Node {
return new Node(this, 'HTTP Status', this._statusCode);
}
/**
* Length of the response body
*/
public length(): Node {
return new Node(this, 'Length of Response Body', this._body.length);
}
/**
* Load time of request to response
*/
public loadTime(): Node {
return new Node(this, 'Load Time', this.scenario.getRequestLoadTime());
}
/**
* Get URL of the current page
*/
public url(): Node {
return new Node(this, 'URL', this.getUrl());
}
/**
* Get the path of the current page
*/
public path(): Node {
return new Node(this, 'Path', new URL(this.getUrl()).pathname);
}
}