A custom rule consists of one javascript function receiving an Page
object as first argument and a callback
function as the second argument that needs to be called with an valid rule result when the rule is done.
If you call done
with nil
as the argument, the rule result will be removed from the result list.
- Page Object
- RuleContext (rule helper methods)
Some example rules (more here)
Always returns the host of the visited site
function(page, done) {
var documentEndEvent = page.documentEndEvent();
// Return if no documentEndEvent (and so location) found
if (!documentEndEvent) { return null; }
var { location } = documentEndEvent;
//you can either return
//return { label: 'DEBUG', type: 'info', message: `Loaded ${location.href}`};
//return this.createResult(label, msg, type, [what]*); //what is a kind of sublable attached to the front of the message
return done(this.createResult('DEBUG', `Loaded ${location.href}`, 'info'));
}
Counts the occurrence of paragraph elements after document idle
function(page, done) {
var documentIdleEvent = page.documentIdleEvent();
// Return if no documentIdleEvent (and so location) found
if (!documentIdleEvent) { return null; }
var { document } = documentIdleEvent;
var countElements = document.querySelectorAll('p').length;
return done(this.createResult('STATS', `found ${countElements} paragraph elements`));
}
Example of an async rule
function(page, done) {
setTimeout(function() {
done(this.createResult('STATS', 'I fired after 5 seconds', 'info'));
}, 5000);
}
The page
-object is basically a collection of events. This event-collection holds all the occurred events during the page load.
- onBeforeNavigate
- onCommitted
- onBeforeSendHeaders
- onBeforeRequest
- onCompleted
- responseHeaders
- documentEnd
- documentIdle
additional custom event that have additonal information about the envirment
- fetch - a static represenation of the DOM via the window.fetch event (an unscripted envirment)+
An page
instance provides the following methods to easely filter for relevant events.
Returns the full unfiltered list of events.
function(page) {
var allEvents = page.events();
return this.createResult('DEBUG', `Events count: ${allEvents.length}`);
}
Returns a list (Array) of events for the given type.
function(page) {
var allOnCommittedEvents = page.eventsOfType('onCommitted');
return this.createResult('DEBUG', `onCommitted count: ${allOnCommittedEvents.length}`);
}
Returns the first event of the given type.
Some events can occur multiple times during a page request (for example onHeadersReceived
, onBeforeRequest
, onCommitted
, …).
function(page) {
var onHeadersReceivedEvent = page.firstEventOfType('onHeadersReceived');
var statusCode = onHeadersReceivedEvent.statusCode;
return this.createResult('DEBUG', `First statusCode: ${statusCode}`);
}
Like firstEventOfType
except it returns the last event of the given type.
function(page) {
var onHeadersReceivedEvent = page.lastEventOfType('onHeadersReceived');
var statusCode = onHeadersReceivedEvent.statusCode;
return this.createResult('DEBUG', `Last statusCode: ${statusCode}`);
}
Returns a special event containing document
(a DOMParser
instance representing the DOM before window.onLoad
), location
object, and the pure html
as string.
function(page) {
var documentEndEvent = page.documentEndEvent();
var { document, location, html } = documentEndEvent;
var host = location.host;
var divs = document.querySelectorAll('div').length;
return this.createResult('DEBUG', `${divs} div elements found on ${location.host}`);
}
Like documentEndEvent
except it represents the DOM, location and HTML after window.onLoad
.
- page.domContentLoadedEvent()
- page.fetchEvent()
- page.getStaticDom() //most of the time this is the DOM you want to test
- page.getDocumentEndDom()
- page.getDomContentLoadedDom()
- page.getFetchedDom()
- page.getIdleDom() //this is the DOM if you care about the final rendered DOM pre user interaction DOM
- page.getLocation() //current location of the page (during the document Idle event)
- page.getLocation('static') //URL location of the static DOM
- page.getHttpHeaders() // the HTTP response headers of the initial GET request
- page.getHttpHeaders('last') // the HTTP response headers of the lat GET request (i.e. if there were redirects), all key values are lowercase
- page.getRawHttpHeaders(['last']) //same as above, but un-noramlized
- TODO other helper methods
Each function inside RuleContext.js is available inside every rule via the this
.
Dont forget to run > grunt --reload-extension
or manually reload the extension when modifying the extension code.
Returns a valid rule result (an object with the following keys: label, message and type).
function(page) {
var documentEndEvent = page.documentEndEvent();
var { document, location, html } = documentEndEvent;
var host = location.host;
var divs = document.querySelectorAll('div').length;
return this.createResult('DEBUG', `${divs} div elements found on ${location.host}`);
}
Use this method if you need to make an cross site fetch request inside your rule. Due to some restrictions this is not the native fetch method but it behaves quite similar.
The response is a plain object containing the following keys:
{
body: [STRING](The HTML body of the requested site)
ok: [BOOLEAN](If the request was successful)
redirected: [BOOLEAN](If any redirect occurred)
status: [INTEGER](HTTP-Statuscode)
statusText: [STRING](HTTP-Statustext)
}
Example:
function(page, done) {
var pageToLoad = 'https://google.com';
this.fetch(pageToLoad, { method: 'GET' }, (response) => {
done(this.createResult('INFO', `${response.status}: Page size from ${pageToLoad) is ${response.body.length}`));
});
}