Skip to content

Latest commit

 

History

History
224 lines (150 loc) · 5.65 KB

README.md

File metadata and controls

224 lines (150 loc) · 5.65 KB

Pincers Build Status

Pincers is a jQuery inspired web automation framework with multiple backend support.

Backend support:

  • webdriver: full
  • nokogiri: search and properties only
  • nokogiri-on-line: TBA, this will be a nokogiri based implementation with support of some basic navigation features.

Basic usage

Create a new pincers root context from a webdriver session:

pincers = Pincers.for_webdriver driver

Or from a nokogiri document

pincers = Pincers.for_nokogiri document

Basic Navigation

If you are using webdriver, the first thing to do is to navigate to some url:

pincers.goto 'www.crabfarm.io'

Searching

Consider the following HTML structure for the examples below

<body>
  <div id="first-parent" class="my-class">
    <p id="first-child" class="child-class other-class">Foo</p>
    <p id="second-child" class="child-class">Bar</p>
  </div>
  <div id="second-parent" class="my-class">
    <p id="third-child" class="child-class">Imateapot</p>
  </div>
  <p id="fourth-child" class="child-class">Imateapot</p>
</body>

Search for elements matching a given selector using css:

pincers.css('.my-class') # will select first-parent and second-parent

This will return another context contaning all elements matching the given selector. The context object is an enumarable that yields single element contexts, so you can use pincers methods on separate elements too:

pincers.css('.my-class').map do |div|
  div.css('.child-class') # div is also a contex!
end

Pincers contexts also have first and last methods that return the first and last element wrapped on a separate context.

pincers.css('.my-class').first # first is also a context!

Searching over a context will search among all contained elements children:

parents = pincers.css('.my-class')
parents.css('.child-class') # will select all childs except fourth-child

Single element properties

There are several methods that when called on a context will only apply to the first element contained by that context:

Retrieve the text contents from the first matching element.

pincers.css('.child-class').text # = 'Foo'

Retrieve an attribute from the first matching element:

pincers.css('.child-class')[:id] # = 'first-child'

Retrieve the tag name from an element:

pincers.css('.child-class').tag # = 'p'

Retrieve an array with all classes from the first matching element:

pincers.css('.child-class').classes # = ['child-class', 'other-class']

Element interaction

The following methods change the element or document state and are only available in some backends. Like the Single Element Properties, when called, these methods only affect the first element in the context.

To set the text on a text input

pincers.css('input#some-input').set 'sometext'

Choose a select box option by it's label

pincers.css('select#some-select').set 'Some Label'

Choose a select box option by it's value

pincers.css('select#some-select').set 'some-value'

Change a checkbox or radio button state

pincers.css('input#some-checkbox').set # check
pincers.css('input#some-checkbox').set false # uncheck

Click on a button (or any other element)

pincers.css('a#some-link').click

Root properties

The root context has some special methods to access document properties.

To get the document title

pincers.title

To get the document url

pincers.url
pincers.uri # same as url but returns an URI object

To get the document driver itself (webdriver driver or nokogiri root node)

pincers.document

Advanced topics

Navigating frames

Pincers operations can only target one frame at a time. By default, the top frame is selected when location is changed. As with urls, to switch to a diferent frame use the goto method with the frame: option:

pincers.goto frame: css('#my-frame')
pincers.text # this will return the '#my-frame' frame contents

You can also use a selector directly

pincers.goto frame: '#my-frame'

To navigate back to the top frame after working on a child frame use the special identifier :top:

pincers.goto frame: :top

Waiting for a condition

In javascript enabled backends like webdriver, sometimes it's necessary to wait for an element to appear before doing something with it:

pincers.css('#my-async-stuff', wait: :present)

When using the webdriver backend, it's posible to wait on the following states:

  • :present: wait for element to show up in the DOM
  • :visible: wait for element to be visible
  • :enabled: wait for input to be enabled
  • :not_present: wait for element to be removed from DOM
  • :not_visible: wait for element to be hidden

By default, the waiting process times out in 10 seconds. This can be changed by setting the Pincers.config.wait_timeout property or by calling the search function with the timeout: option:

pincers.css('#my-async-stuff', wait: :present, timeout: 5.0)

Accessing the underlying backend objects

Sometimes (hopefully not too often) you will need to access the original webdriver or nokogiri api. Pincers provides a couple of methods for you to do so.

To get the document handler itself call document on the root context.

pincers.document # webdriver driver or nokogiri root node

To get the contained nodes on a pincers context use elements

pincers.css('.foo').elements # array of webdriver elements or nokogiri nodes.