Methods and Features
Last updated
Was this helpful?
Last updated
Was this helpful?
These can be used any where within your specs:
- executes code on the client
- executes code on the client and the server
- mounts a hyperstack component in an empty window
- specifies a block of code to be executed before the first call to mount
, isomorphic
or on_client
- insert some html into a page
- allows options to be specified globally
- same as on_client
but no value is returned
- resets the page environment
- adds a CSS class
- specifies how big the client window should be
- returns any ActiveModel attributes loaded on the client
These methods are used after mounting a component to retrieve events sent outwards from the component:
These can be used within expectations replacing the to
and not_to
methods. The expectation expression must be inclosed in a block.
These methods have the following aliases to make your specs more readable:
in addition
The following methods are used primarly at a debug break point, most require you use binding.pry as your debugger:
HyperSpec comes integrated with Chrome and Chrome headless webdrivers. The default configuration will run using Chrome headless. To see what is going on set the DRIVER
environment variable to chrome
no_reset
flagBy default the client environment will be reinitialized at the beginning of every spec. If this is not needed you can speed things up by adding the no_reset
flag to a block of specs.
See the last section below for known issues.
on_client
methodThe on_client method takes a block. The ruby code inside the block will be executed on the client, and the result will be returned.
If the block returns a promise Hyperspec will wait for the promise to be resolved (or rejected) before returning. For example:
HyperSpec will do its best to reconstruct the result back on the server in some sensible way. Occasionally it just doesn't work, in which case you can end the block with a
nil
or some other simple expression, or use therun_on_client
method, which does not return the result.
It is often useful to pass variables from the spec to the client. Hyperspec will copy all your local variables, memoized variables, and instance variables known at the time the on_client
block is compiled to the client.</br>
Note that memoized variables are not initialized until first accessed, so you probably want to use the let! method unless you are sure you are accessing the memoized value before sending it to the client.
The value of instance variables initialized on the client are preserved across blocks executed on the client. For example:
include_vars
can be set to
an array of symbols: only those vars will be copied,
a single symbol: only that var will be copied,
any other truthy value: all vars will be copied (the default)
or nil, false, or an empty array: no vars will be copied.
exclude_vars
can be set to
an array of symbols - those vars will not be copied,
a single symbol - only that var will be excluded,
any other truthy value - no vars will be copied,
or nil, false, or an empty array - all vars will be copied (the default).
Examples:
Note that the exclude_vars list will take precedence over the include_vars list.
The exclude/include lists can be overridden on an individual call to on_client by providing a hash of names and values to on_client:
isomorphic
methodThe isomorphic
method works the same as on_client
but in addition it also executes the same block on the server. It is especially useful when doing some testing of ActiveRecord models, where you might want to modify the behavior of the model on server and the client.
The first time a spec runs code on the client, it has to initialize a browser context. You can use the client_options
(aka client_option
) method to specify the following options when the page is loaded.
time_zone
- browsers always run in the local time zone, if you want to force the browser to act as if its in a different zone, you can use the time_zone option, and provide any valid zone that the rails in_time_zone
method will accept.
Example: client_option time_zone: 'Hawaii'
clock_resolution
: Indicates the resolution that the simulated clock will run at on the client, when using the TimeCop gem. The default value is 20 (milliseconds).
render_on
: :client_only
(default), :server_only
, or :both
no_wait
: After the page is loaded the system will by default wait until all javascript requests to the server complete before proceeding. Specifying no_wait: true
will skip this.
javascript
: The javascript asset to load when mounting the component. By default it will be application
(.js is assumed). Note that the standard Hyperstack configuration will compile all the client side Ruby assets as well as javascript packages into the application.js
file, so the default will work fine.
style_sheet
: The style sheet asset to load when mounting the component. By default it will be application
(.css is assumed).
controller
- (expert zone!) specify a controller that will be used to mount the
component. By default hyper-spec will build a controller and route to handle the request from the client to mount the component.
Any other options not listed above will be passed along to the Rail's controller render
method. So for example you could specify some other specific layout using client_option layout: 'special_layout'
Note that this method can be used in the before(:each)
block of a spec context to provide options for all the specs in the block.
The mount
method is used to render a component on a page:
The mount
method has a few options. In it's simplest form you specify just the name of the component that is already defined in your hyperstack code and it will be mounted.
You can add parameters that will be passed to the component as in the above example. As the above example also shows you can also define code within the block. This is just shorthand for defining the code before hand using on_client
. The code does not have to be the component being mounted, but might be just some logic to help with the test.
In addition mount
can take any of the options provided to client_options
(see above.) To provide these options, you must provide a (possibly) empty params hash. For example:
Components receive parameters, and may send callbacks and events back out. To test if a component has sent the appropriate data you can use the following methods:
callback_history_for
last_callback_for
clear_callback_history_for
event_history_for
last_event_for
clear_event_history_for
Note that you must declare the params as type
Proc
, or use thefires
method to declare an event for the history mechanism to work.
before_mount
Specifies a block of code to be executed before the first call to mount
, isomorphic
or on_client
. This is primarly useful to add to an rspec before(:each)
block containing common client code needed by all the specs in the context.
Unlike
mount
,isomorphic
andon_client
,before_mount
does not load the client page, but will wait for the first of the other methods to be called.
add_class
Example: add_class :some_class, borderStyle: :solid
adds a class with style border-style: 'solid'
run_on_client
same as on_client
but no value is returned. Useful when the return value may be too complex to marshall and unmarshall using JSON.
reload_page
Shorthand for mount
with no parameters. Useful if you need to reset the client within a spec.
size_window
Indicates the size of the browser window. The values can be given either symbolically or as two numbers (width and height). Predefined sizes are:
:small
: 480 x 320
:mobile
640 x 480
:tablet
960 x 64,
:large
1920 x 6000
:default
1024 x 768
All of the above can be modified by providing the :portrait
option as the first or second parameter.
So for example the following are all equivalent:
size_window(:small, :portrait)
size_window(:portrait, :small)
size_window(320, 480)
attributes_on_client
returns any ActiveModel
attributes loaded on the client. HyperModel will normally begin a load cycle as soon as you access the attribute on the client. However it is sometimes useful to see what attributes have already been loaded.
insert_html
takes a string and inserts it into test page when it is mounted. Useful for testing code that is not dependent on Hyper Components. For example an Opal library that adds some jQuery extensions.
These can be used within expectations replacing the to
and not_to
methods. The expectation expression must be inclosed in a block.
For example:
The above expectation is short for saying:
These methods have the following aliases to make your specs more readable:
to_on_client
on_client_to_not
on_client_not_to
to_not_on_client
not_to_on_client
to_then
then_to_not
then_not_to
to_not_then
not_to_then
The then
variants are useful to note that the spec involves a promise, but it does no explicit checking that the result comes from a promise.
In addition the with
method can be chained with the above methods to pass data to initialize local variables on the client:
These methods are primarily designed to help debug code and specs.
c?
Shorthand for on_client
, useful for entering expressions in the pry console, to investigate the state of the client.
to_js
Takes a block like on_client
but rather than running the code on the client, simply returns the resulting code. This is useful for debugging obscure problems when the Opal compiler or some feature of Hyperspec is suspected as the issue.
ppr
Takes a block like on_client
and prints the result on the client console using JS console.log. Equivalent to doing
This is useful when the result cannot be usefully returned to the server, or when the result of interest is better looked at as the raw javascript object.
debugger
This psuedo method can be inserted into any code executed on the client. It will cause the code to stop, and enter a javascript read-eval loop, within the debug console.
Unfortunately ATM we do not have the technology to enter a Ruby read-eval loop at an arbitrary point on the client.
Note: due to a bug in the Opal compiler your code should not have
debugger
as the last expression in a method or a block. In this situation add any expression (such as nil) after the debugger statement.
open_in_chrome
By default specs are run with headless chrome, so there is no visible browser window. The open_in_chrome
method will open a browser window, and load it with the current state.
You can also run specs in a visible chrome window by setting the DRIVER
environment variable to chrome
. i.e. (DRIVER=chrome bundle exec rspec ...
)
pause
The method is typically not needed assuming you are using a multithreaded server like Puma. If for whatever reason the pry debug session is not multithreaded, and you want to try some kind of experiment on the javascript console, and those experiments make requests to the server, you may not get a response, because all threads are in use.
You can resolve this by using the pause
method in the debug session which will put the server debug session into a non-blocking loop. You can then experiment in the JS console, and when done release the pause by executing go()
in the javascript debug console.
visit
and the Application LayoutUpvote issue 398 if this presents a big problem for you.
This has been fixed in Parser version 2.7 which works with Opal 1.0 So the issue is only with older versions of Opal.
You may get an error like this when running a spec:
The problem is the unparser incorrectly generates hash.[]("foo") += 1
instead of hash['foo'] += 1
.
The good news its pretty easy to find such expressions and replace them with something like
hash["foo"] = hash["foo"] + 1
, - the expression will be evaluated on the client, and matched on the server.
- can be chained with the above methods to pass data to initialize local variables on the client
- returns the ruby code compiled to JS.
- alias for on_client
.
- print the results of the ruby expression on the client console.
- Sets a debug breakpoint on code running on the client.
- Opens a chrome browser that will load the current state.
- Halts execution on the server without blocking I/O.
You can use the to control the flow of time within your specs. Hyperspec will coordinate things with the client so the time on the client is kept in sync with the time on the server. So for example if you use Timecop to advance time 1 day on the server, time on the browser will also advance by one day.
See the section for how to control the client time zone, and clock resolution.
Be especially careful of this when using the as instance variables will retain their values between each spec in this mode.
By default all local variables, memoized variables, and instance variables in scope in the spec will be copied to the client. This can be controlled through the include_vars
and exclude_vars
.
You can do the same thing on expectations using the with
method - See .
include_vars
: white list of all vars to be copied to the client. See for details.
exclude_vars
: black list of all vars not to be copied to the client. See for details.
Hyperstack components can be prerendered on the server. The render_on
option controls this feature. For example server_only
is useful to insure components are properly prerendered. See the mount
method for more details on rendering components
Adds a CSS class. The first parameter is the name of the class, and the second is a hash of styles, represented in the React
By default HyperSpec will copy all local variables, memoized variables, and instance variables defined in a spec to the client. The specific variables can also be white listed and black listed. The with
method overrides any white or black listed values. So for example if you prefer to use the more explicit with
method to pass values to the client, you can add client_option exclude_vars: true
in a before(:all)
block in your spec helper. See for details.
Currently this is not well integrated (see ). If you want to visit a page on the website using visit
, the following will not work: Timecop integration, and the insert_html
and before_mount
methods. You will also have to execute this line in your spec: