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:
- CircleCI:
- SemaphoreCI 2.0: (not yet available)
- TravisCI:
Installation
In Gemfile:
gem 'isomorfeus-puppetmaster'
, then bundle install
Also requires the following npm modules with recommended versions:
- puppeteer 10.2.x - for the chrome driver
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:
- Assign a rack app
- 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
- Find something
- 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