Permalink
Browse files

Add @using(..) helper to pass objects to PhantomJS.

This hack has the same limitations as when passing variables from PhantomJS
to Lotte - it can only work on simple types and cannot serialize functions,
regular expressions, etc.

It is still better than having nothing or having to write the code yourself
each time a variable from a different environment is needed.
  • Loading branch information...
1 parent 9ebbca7 commit 4ce480c43da414c563c714a8d7a4cad935de1c2d @StanAngeloff committed Dec 9, 2011
Showing with 61 additions and 1 deletion.
  1. +24 −1 README.md
  2. +19 −0 lib/inject/test/page.js
  3. +18 −0 test/test_using.coffee
View
@@ -301,9 +301,32 @@ Objects are serialized before they leave the page sandbox and unserialized back
throw 'exit'
```
+Lotte comes with a workaround which allows you to pass variables to the PhantomJS environment.
+This hack has the same limitations as outlined above (it uses `JSON.stringify` internally):
+
+- **`@using(hash, block)`**
+
+ `hash` is a `key: value` object where:
+
+ - `key` must be a valid identifier and defines the name of the variable within the PhantomJS environment
+ - `value` must be serializable and contains the value of the variable
+
+ `block` is either a function or a string.
+
+ Returns a `Function` string with all `key: value` pairs from `hash` as arguments.
+
+```coffeescript
+@open 'https://github.com', ->
+ @describe '@using(..)', ->
+ expected = 'git'
+ @$('h2').first @using { expected }, (element) -> element.innerHTML.indexOf(expected) is 0
+ throw 'exit'
+```
+
#### Document Queries
-To work around those limitations and to abstract the boilerplate needed to access the DOM of a page, Lotte comes with a jQuery-like query function:
+There is a lot of boilerplate code required to access the DOM of a page.
+Lotte comes with a jQuery-like query function to abstract some of the most common operations:
- **`@$(selector)`**
@@ -81,6 +81,25 @@ TestPage.prototype.bind = function TestPage_bind(block) {
};
};
+TestPage.prototype.using = function TestPage_using(object, block) {
+ var args = [], values = [];
+ for (var key in object) {
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
+ args.push(key);
+ values.push(JSON.stringify(object[key]));
+ }
+ }
+ return '\n\
+ function() {\n\
+ var _self = this,\n\
+ _args = Array.prototype.slice.call(arguments);\n\
+ return (function(' + args.join(', ') + ') {\n\
+ return (' + block.toString() + ').apply(_self, _args);\n\
+ })(' + values.join(', ') + ');\n\
+ }\n\
+ ';
+};
+
TestPage.prototype._defineGetters = function TestPage_defineGetters() {
this.__defineGetter__('top', function() {
var top = null;
@@ -0,0 +1,18 @@
+@base 'http://' + phantom.args[0] + ':' + phantom.args[1]
+@title 'localhost.localdomain'
+
+@open '/', '@using(..)', ->
+ @describe 'should export variables across environments', ->
+ value = 'argument names can be omitted'
+ @assert.equal value, @page.evaluate @using { value }, -> value
+ value = 'arguments are still available when function signature is different'
+ @assert.equal value, @page.evaluate @using { value }, (x, y, z) -> value
+ @success()
+ @describe 'should export complex types', ->
+ object = { hello: [false, value = 'World!'] }
+ @assert.equal value, @page.evaluate @using { object }, -> object.hello.pop()
+ @success()
+ @describe 'should work with assertions', ->
+ html = @$('h1').innerHTML
+ @$('h1').first @using { html }, (element) -> element.innerHTML is html
+ @success()

0 comments on commit 4ce480c

Please sign in to comment.