isomorfeus-puppetmaster

A framework for acceptance tests or simply running tests in a headless browser. Comes with drivers for chrome headless. Allows for writing javascript browser tests in pure ruby.

Community and Support

At the Isomorfeus Framework Project

Running on:

Installation

In Gemfile: gem 'isomorfeus-puppetmaster', then bundle install

Also requires the following npm modules with recommended versions:

Simply install them in your projects root. Puppetmaster also depends on isomorfeus-speednode, which will be installed automatically. Speednode will pickup the node modules then from the projects root node_modules directory.

Configuration

Puppetmaster provides these drivers:

  • chromium - a real browser, headless, fast
  • chromium_debug - opens a chromium browser window with devtools enabled, useful for debugging tests

Chrome is the default driver. Selecting another driver, for example firefox:

Isomorfeus::Puppetmaster.driver = :chromium_debug

Puppetmaster provides support for this rack server:

  • iodine Iodine is the default rack server, automatically configured.

Getting the app ready and running:

  1. Assign a rack app
  2. Boot the app

For Example:

Isomorfeus::Puppetmaster.app = TestApp
Isomorfeus::Puppetmaster.boot_app

Include the Puppetmaster DSL in the spec_helper.rb:

RSpec.configure do |config|
  config.include Isomorfeus::Puppetmaster::DSL
end

Ready to play!

Terminology

There are Browsers which may have windows or tabs, which translate to targets or pages which may contain documents or frames which consist of elements or nodes. In Puppetmaster, which is focusing on headless testing, the main "thing" is just a document. Its possible to open many documents at once, but what exactly a document is contained in, a window or tab or browser or target or whatever, is not of interest. A document consists of nodes. Simply working with just documents and nodes makes testing a lot simpler.

document
    |____head (is a node)
    |      |
    |      |___more nodes
    |      |___...
    | 
    |____body (is a node)
           |
           |___more nodes
           |___...

Basic usage pattern

  1. Find something
  2. Interact with it

Documents

The drivers open a empty default document, to use that and go to the apps root page:

doc = visit('/')

This provides the document doc which can further be used to interact with. To go to another location, call visit or goto on that doc:

doc.visit('/login') # or
doc.goto('/login')

To open another document:

doc2 = open_new_document('/play')

Both open documents can then be independently interacted with:

doc.visit('/go')
doc2.goto('/location')

Documents and Ruby

Ruby can be executed within documents by simply providing a block or a string:

doc.evaluate_ruby do
  $document['my_id'].class_names
end

# or

doc.evaluate_ruby "$document['my_id'].class_names"

The complete API of opal-browser is available.

Documents and Javascript

Javascript can be be evaluated within documents by simply providing a string:

doc.evaluate_javascript '1+1' # => 2

Executing Javascript

TODO

DOM changes by Javascript, Timing

TODO

Nodes

Finding Nodes ...

Nodes can be found by CSS selectors or XPath queries. Node can be found from the document or or other nodes as root.

... with CSS selectors

Documents and nodes provide methods for finding single nodes or a group of nodes with CSS selectors. Examples: Find a single node in a document:

node1 = doc.find('div') # finds the first div in the document
node2 = doc.find('#super') # find node with id="super"

Find a single from another node:

node3 = node1.find('div') # find first div within the node

Find multiple nodes in a document or from a node:

node_array1 = doc.find_all('div') # finds all div's in a document
node_array2 = node2.find_all('div') # find all div's within node2

... with XPath queries

Documents and nodes provide methods for finding single nodes or a group of nodes with Xpath queries. Examples: Find a single node in a document:

node1 = doc.find_xpath('//div') # finds the first div in the document
node2 = doc.find_xpath("//div[contains(@id,'super')]") # find div with id="super"

Find a single from another node:

node3 = node1.find_xpath('//div') # find first div within the node

Find multiple nodes in a document or from a node:

node_array1 = doc.find_all_xpath('//div') # finds all div's in a document
node_array2 = node2.find_all_xpath('//div') # find all div's within node2

Interacting with nodes

Puppetmaster provides methods for emulating user interactions with nodes or documents.

Mouse

node1.click

TODO

Keyboard

node4 = doc.find('input')
node4.type_keys('Message')

TODO

Fingers

TODO

Tests

To run tests:

  • clone repo
  • bundle install
  • bundle exec rake