Minium Instructions
Step definitions are implemented using Minium instructions. In this section, you will get to know the basic types of Minium instructions.
Elements
Elements
is the most important concept in Minium. It represents an instruction (from now on, we'll call
them Minium expressions) that will eventually evaluate into elements that we want to interact with. Notice that
we didn't say web elements, because currently Minium can be extended to other test platforms,
even non-Web ones like mobile or visual pattern recognition ones like Sikuli).
Elements
are normally lazy (there are some exceptions), and they can be evaluated several times with different
results, which means that the same Minium expression can be reused. Besides, its chainable method API always returns
a new Minium expression, so Minium expressions are by nature immutable.
Minium WebElements
is a specialization of Elements
for browser testing (it is intentionally the plural of Selenium
WebDriver WebElement
). It uses Selenium WebDriver API under the hood.
Consider the following Minium expression:
searchbox = $("#container").find(":text").filter("[name=searchbox]");
That expression itself does not communicate with the browser, because it was not evaluated yet. For an expression to be evaluated, one of the following invocations need to occur:
- A method with a return value other than a subclass of
Elements
is invoked, like:
searchbox.text();
- An interaction method is called:
searchbox.fill("Minium can!");
Under the hood
Let's see what happens under the hood when the following code is executed:
searchbox = $("#container").find(":text").filter("[name=searchbox]");
searchbox.text()
- Minium expression
$("#container").find(":text").filter("[name=searchbox]")
, which chains methods.find(selector)
and.filter(selector)
returns aWebElements
object representing the corresponding expression chain. At this point, no communication with the browser occurred yet. - It is only when the
.text()
method is called, which returns aString
, that the expression is actually going to be evaluated. Minium generates the javascript code required for evaluating the corresponding jQuery expression and then sends the code to the browser to be executed. - The generated javascript code will require object minium.jQuery to be defined in the page scope. Minium will automatically initialize the minium object in the page scope, including a custom jQuery version in minium.jQuery, before the first expression is evaluated. In order to do so, an additional request needs to be sent to the browser.
Positional filters
Minium provides positional filters for Minium elements expressions, such as
.leftOf()
, .below()
or .overlaps()
. Those methods actually use the
rendered position in the page to determine if elements can be found relative to
others.
var header = $("th").withText("Code");
var cell = $("td").withText("A14").below(header);
var deleteBtn = $("button").rightOf(cell);
Select cells in tables
Selecting cells in tables based on their values and columns can be hard. Minium positional filters can ease that process, as we will see. So, first things first: let's ensure our browser is at Minium Mail Inbox:
browser.get("http://minium.vilt.io/sample-app/#/folders/inbox");
Then let's get variables to identify both table headers and table value cells:
var headers = $("#mail-list th")
var cells = $("#mail-list td");
var recipientsHeader = headers.withText("Recipients");
var recipientsCells = cells.below(recipientsHeader);
We can now filter cells with "Minium Bot" on it, for instance:
var recipientCell = recipientsCells.withText("Minium Bot")
Now it's easy to click the checkbox of that row:
var itemCheckbox = $(":checkbox").leftOf(recipientCell);
itemCheckbox.click(); // this will toggle the checkbox
You can find more details about the available methods for selecting web elements on Web Elements API.
Interactions
Interactions are another key concept in Minium. They represent user interactions with the browser, like
clicking, filling input fields, or even waiting that some element exists. Objects that can perform interactions
are known as Interactable
. Typically, all Elements
/ WebElements
are interactable. The Interactable
interface
provides interactions behind methods like .click()
or .fill()
.
The most important Interactable
interfaces are:
MouseInteractable
: allows mouse operations with elements, like clicking, moving mouse around, etc.KeyboardInteractable
: allows keyboard operations with elements, like pressing a key, typing text, etc.WaitInteractable
: wait conditions on elements
Interactions have a very important behaviour: they try the best they can to fulfill their task. For instance, let's say we have the following expression:
field = $(":text").unless(".loading");
This expression represents all text input elements in the page unless there is some element with
loading
CSS class (in that case, it will then evaluate to an empty set).
Now let's try to interact with it:
field.fill("Minium can!");
At this point, we have an interaction being called, and for that reason Minium will evaluate field
.
If there is some .loading
element in the page (for instance, some AJAX is being performed and the page
displays a loading element to let us know that), then field
will evaluate to an empty set, and for that
reason, it cannot be filled with text. At this point, Minium will wait a specified interval
period and then
retry the evaluation. Two situations may occur:
- Eventually, the expression evaluates to a non-empty set. Minium will then grab the first element of that evaluated set and will fill it with the specified text.
- the expression keeps evaluating to an empty set, and the total period surpasses a specified
timeout
period. At this point, interaction is aborted and aTimeoutException
is thrown.
Wait Interactions
WaitInteraction
s are a slightly different kind of interactions, first of all because they don't actually
change state in the browser.
Moreover, some WaitInteraction
's (like .checkForUnexistence()
and .waitForUnexistence()
) are only able to fulfill their task when the expression, to which they apply to, evaluate to an empty set.
WaitInteractable
provides the following WaitInteraction
methods:
.waitforExistence( [waitingPreset] )
: waits until the expression evaluates to at least one element, and returns that expression.waitforUnexistence( [waitingPreset] )
: waits until the expression evaluates to no element at all, and returns that expression.checkForExistence( [waitingPreset] )
: tries to wait until the expression evaluates to at least one element, returning true. In case a timeout occurs, it will return false.checkForExistence( [waitingPreset] )
: tries to wait until the expression evaluates to no element at all, returning true. In case a timeout occurs, it will return false.waitTime(time, units)
: waits a specified ammout of time, returning the expression after that time has passed
Notice that an waitingPreset
can be provided, which is a String
that represents a pair of interval
and timeout
periods.
That can be configured globaly, as well as the default interval
and timeout
periods. By default, there is a immediate
waiting
preset that doesn't wait at all (for instance, $(:text).checkForExistence("immediate")
will return true or false immediately).
Very Important: having $(":text").checkForUnexistence()
is not the same as !$(:text).checkForExistence()
, because
in the first one, it will wait until $("text")
evaluates to an empty set, and in the second one it will wait for
$("text")
to evaluate to a non-empty set. Don't forget that an interaction always tries to fulfill its task,
and for .checkForExistence()
/ .checkForUnexistence()
that means returning true!
You can find more details about the available methods for interacting with web elements on Interactable API.
Assertions
Minium includes Expect library for assertions, and extends it to add Minium-specific methods.
For instance, to assert the existence of an element:
var composeBtn = $("compose");
expect(compose).to.exist();
Or, if you want to check that some element has a specific text:
var composeBtn = $("compose");
expect(compose).to.have.text("Compose");
You can find more documentation on Assertions API.