Skip to content

Commit

Permalink
Network intercept functions, wait function, silence page errors (#9)
Browse files Browse the repository at this point in the history
1. Added some of Phantom's network interception functions.
2. Page errors are console logged by default. Added functions silencePageErrors, getSilencedPageErrors, and clearPageErrors to stop this default behavior.
3. Added the Page.wait function for convenience.
4. Fixed bug where page.evaluate returning undefined is not handled.
  • Loading branch information
dgendill authored Feb 4, 2018
1 parent 85a89d6 commit f535dda
Show file tree
Hide file tree
Showing 8 changed files with 341 additions and 24 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ cd examples-output
../node_modules/.bin/phantomjs stream.js
```

## Tests
## Testing

Assuming you have purescript and phantomjs installed, run the following in the project root...

Expand All @@ -76,3 +76,7 @@ Or if you're using [phantomjs-prebuilt](https://www.npmjs.com/package/phantomjs-
You can also run the tests, in the [purescript-docker image](https://github.com/Risto-Stevcev/purescript-docker).
If you're using docker, follow the instructions in the comments of `test.sh` to get a working container. You can then run the
tests inside of the container by running `./test.sh` on the host, which will run `pulp --watch test` inside the container.

If you'd like to [test using console logging](https://medium.com/@mattdenner/purescript-3-914c51afe194) you can use [spy]
(https://pursuit.purescript.org/packages/purescript-debug/3.0.0/docs/Debug.Trace#v:spy) or `traceAnyM` from [purescript-debug]
(https://pursuit.purescript.org/packages/purescript-debug).
10 changes: 7 additions & 3 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"name": "purescript-phantom",
"description": "Purescript bindings to PhantomJS",
"author": "Risto Stevcev",
"authors": [
"Risto Stevcev",
"Dominick Gendill"
],
"license": "MIT",
"ignore": [
"**/.*",
Expand All @@ -24,11 +27,12 @@
"purescript-foreign": "^4.0.1",
"purescript-generics-rep": "^5.3.0",
"purescript-datetime": "^3.3.0",
"purescript-encoding": "^0.0.4"
"purescript-encoding": "^0.0.4",
"purescript-nullable": "^3.0.0"
},
"devDependencies": {
"purescript-psci-support": "^3.0.0",
"purescript-test-unit": "^13.0.0",
"purescript-debug": "^3.0.0"
"purescript-debug": "^3.0.0"
}
}
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "purescript-phantom",
"version": "3.0.0",
"version": "3.1.0",
"description": "Purescript bindings to PhantomJS",
"main": "index.js",
"directories": {
Expand All @@ -17,7 +17,10 @@
"purescript",
"phantomjs"
],
"author": "Risto Stevcev",
"contributors": [
"Risto Stevcev",
"Dominick Gendill"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/purescripters/purescript-phantom/issues"
Expand Down
152 changes: 141 additions & 11 deletions src/PhantomJS/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ function alwaysCancel(cancelError, onCancelerError, onCancelerSuccess) {
onCancelerSuccess();
}

function defaultErrorHandler(msg, trace) {

var msgStack = [msg];

if (trace && trace.length) {
trace.forEach(function(t) {
msgStack.push(' at ' + (t.function ? t.function + ' ' : '') + '(' + t.file + ':' + t.line + ')');
});
}
console.error(msgStack.join('\n'));

}

var phantomPageGlobal = {
pageCounter : 0,
errors : {}
};


function PhantomPageError(message, stack) {
this.name = 'PhantomPageError';
this.message = message;
Expand All @@ -14,9 +33,11 @@ PhantomPageError.prototype.constructor = PhantomPageError;

exports.createPage_ = function(error, success) {
var webpage = require('webpage').create();
webpage.phantomUniqueId = phantomPageGlobal.pageCounter++;
webpage.onError = defaultErrorHandler;
success(webpage);
return alwaysCancel;
}
};

exports.open_ = function(page) {
return function(url) {
Expand All @@ -34,8 +55,7 @@ exports.open_ = function(page) {
return alwaysCancel;
}
}
}

};

exports.render_ = function(page) {
return function(filename) {
Expand All @@ -53,8 +73,7 @@ exports.render_ = function(page) {
}
}
}
}

};

exports.injectJs_ = function(page) {
return function(filename) {
Expand All @@ -68,7 +87,7 @@ exports.injectJs_ = function(page) {
return alwaysCancel;
}
}
}
};


exports.customHeaders_ = function(page) {
Expand All @@ -79,8 +98,7 @@ exports.customHeaders_ = function(page) {
return alwaysCancel;
}
}
}

};

exports.evaluate_ = function(page) {
return function(fnName) {
Expand All @@ -105,16 +123,128 @@ exports.evaluate_ = function(page) {
}
}, fnName);

if (r.type && r.type == "purescript-phantom-error") {
if (r && r.type && r.type == "purescript-phantom-error") {
// An exception was thrown in the page's context
// so we'll create a custom Error object that
// lets us set the message and stack
error(new PhantomPageError(r.message, r.stack));
} else {
success(r);
}

return alwaysCancel;
}
}
}
};

exports.onResourceRequested_ = function(page) {
return function(error, success) {

page.onResourceRequested = function(request) {
success(request);
}

return alwaysCancel;

}
};

exports.onResourceRequestedFor_ = function(page) {
return function(time) {
var start = Date.now();
var end = start + time;
var requests = [];

return function(error, success) {

window.setTimeout(function() {
success(requests);
}, time);

page.onResourceRequested = function(request) {
if (Date.now() <= end) {
requests.push(request);
}
}

return alwaysCancel;

}
}
};

exports.silencePageErrors_ = function(page) {

phantomPageGlobal.errors[page.phantomUniqueId] = phantomPageGlobal.errors[page.phantomUniqueId] || [];

return function(error, success) {
// http://phantomjs.org/api/webpage/handler/on-error.html
page.onError = function(msg, trace) {
phantomPageGlobal.errors[page.phantomUniqueId].push({
message : msg,
trace : trace
});
};

// success();

return function cancelSilencePageErrors_(cancelError, onCancelerError, onCancelerSuccess) {
page.onError = defaultErrorHandler;
onCancelerSuccess();
}

}
};

exports.getSilencedErrors_ = function(page, just, nothing) {
return function(error, success) {
if (phantomPageGlobal.errors[page.phantomUniqueId]) {
var errors = phantomPageGlobal.errors[page.phantomUniqueId].map(function(e) {
return {
message : e.message,
trace : e.trace.map(function(t) {
return {
file : t.file,
line : t.line,
function : t.function ? just(t.function) : nothing,
}
})
}
});
success(errors);
} else {
success([]);
}

return alwaysCancel;
}
};

exports.clearPageErrors_ = function(page) {
return function(error, success) {
if (phantomPageGlobal.errors[page.phantomUniqueId]) {
phantomPageGlobal.errors[page.phantomUniqueId] = [];
success();
} else {
success();
}

return alwaysCancel;
}
};


exports.waitImpl = function(time) {
return function (error, success) {
setTimeout(function() {
success();
}, time);

function alwaysCancel(cancelError, onCancelerError, onCancelerSuccess) {
onCancelerSuccess();
}

return alwaysCancel;

}
};
Loading

0 comments on commit f535dda

Please sign in to comment.