jasmine-dom-custom-matchers
v1.0.6
Published
Set of 19 jasmine custom matchers to test html DOM.
Downloads
782
Maintainers
Readme
In This Documentation
Description
How does jasmine-dom-custom-matchers
work?
A custom matchers syntax has changed with the release of jasmine 2.0. This library provides 19 custom matchers adapted to the new way of matchers constructing. It allows you to compare DOM Objects relations and states.
What can I use jasmine-dom-custom-matchers
for?
- to check if the actual parameter is HTML Element [see below]
- to check if the actual parameter is HTML Text [see below]
- to check if the HTML Element or HTML Text is appended to the document [see below]
- to check if the expected HTML Element is a descendant of actual HTML Element [see below]
- to check if actual HTML Element or its HTML Element descendants contain expected text [see below]
- to check if expected Node is a child of actual Node [see below]
- to check if actual is n-th child of its parent [see below]
- to check if expected Node is a parent of actual Node [see below]
- to check i actual and expected nodes have got the same HTML Element parent [see below]
- to check if actual HTML Element has got any HTML Element children [see below]
- to check if actual HTML Element is the next sibling of expected HTML Element [see below]
- to check if actual HTML Element is the previous sibling of expected HTML Element [see below]
- to check if HTML Element is empty (has not got any HTML ELement and HTML Text nodes) [see below]
- to check if HTML Element has got any attributes defined [see below]
- to check if HTML Element has got expected attribute (or expected attribute of expected value) [see below]
- to check if HTML Element has got expected class [see below]
- to check if HTML Element (DOM node) has got expected style (computed style) [see below]
- to check if HTML Element (DOM node) has got expected color (computed style) [see below]
- to check if HTML Element has got expected event attached [see below]
DOM Custom Matchers list
expect(actual).toBeHTMLElement(name)
[see below]expect(actual).toBeHTMLText(content)
[see below]expect(actual).toBeDocumentNode()
[see below]expect(actual).toContainHTMLElement(descendant)
[see below]expect(actual).toContainText(content)
[see below]expect(actual).toBeChildOf(parent)
[see below]expect(actual).toBeNthChild(index)
[see below]expect(actual).toBeParentOf(child)
[see below]expect(actual).toHaveSameParent(node)
[see below]expect(actual).toHaveChildren(numOfChildren)
[see below]expect(actual).toBeNextSiblingOf(expected)
[see below]expect(actual).toBePreviousSiblingOf(expected)
[see below]expect(actual).toBeEmpty()
[see below]expect(actual).toHaveAnyAttribute()
[see below]expect(actual).toHaveAttribute(name,value)
[see below]expect(actual).toHaveClass(class)
[see below]expect(actual).toHaveComputedStyle(prop,value)
[see below]expect(actual).toHaveComputedColor(prop,value)
[see below]expect(actual).toHaveEvent(event)
[see below]
Where can I check how jasmine-dom-custom-matchers work?
Examine the Samples described below to find out how you can use DOM custom matchers.
Browser Support
|Chrome|Firefox|IE|Edge|Safari|Opera|iOS Safari|Opera Mini :---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| |4+|2+|9-11|12+|3.1+|9+|3.2+|all|
Methods
expect(actual).toBeHTMLElement(name)
- check if
actual
is [HTML Element] Object. name
parameter is optionalname
parameter if passed, must be of type [String]name
parameter if passed, the matcher checks ifactual
is a [HTML Element] Object of expected tag namename
name
parameter if passed but not of type [String], is ignored as if it was not passed (matcher checks ifactual
is [HTML Element] Object regardless its tag name)- returns false if
actual
is not the [HTML Element] Object - returns false if
actual
is [HTML Element] Object but of not expected tag namename
(if passed) - return true if
actual
is [HTML Element] Object - return true if
actual
is [HTML Element] Object of expectedname
(if passed) - return true regardless
actual
[HTML Element] Object is appended to the DOM or not
expect(actual).toBeHTMLText(content)
- check if
actual
is [HTML Text] Object. content
parameter is optionalcontent
parameter if passed, must be of type [String] or [RegExp]- if the
content
is of type [String] the matcher checks the equality of theactual
text content and expectedcontent
- if the
content
is of type [RegExp] the matcher use String.prototype.match() to check if theactual
text content matches the expectedcontent
regular expression content
parameter if passed but not of type [String] or [RegExp], is ignored as if it was not passed (matcher checks ifactual
is [HTML Text] Object regardless its content)- returns false if
actual
is not the [HTML Text] Object - returns false if
actual
is [HTML Text] Object but does not match expectedcontent
(if passed) - return true if
actual
is [HTML Text] Object - return true if both
actual
is [HTML Text] Object and matches expectedcontent
(if passed) - return true regardless
actual
[HTML Text] Object is appended to the DOM or not
expect(actual).toBeDocumentNode()
- check if
actual
is a [HTML Element] Object or [HTML Text] Object appended into DOM Tree - return false if
actual
is not [HTML Element] Object or [HTML Text] Object or if it is not appended into DOM Tree - returns true if
actual
is [HTML Element] Object or [HTML Text] Object appended into DOM Tree
expect(actual).toContainHTMLElement(descendant)
- check if
actual
HTML Element contains expecteddescendant
- both
actual
anddescendant
must be [HTML Element] Object - return false if
actual
ordescendant
is not the [HTML Element] Object - return false if
actual
does not containdescendant
- return false if
actual
anddescendant
is the same object - return true if
descendant
is a child node ofactual
- return true if
descendant
is a farther descendant ofactual
- return true regardless
actual
[HTML Element] Object and its expected descendant are appended to the DOM or not
expect(actual).toContainText(content)
- check if
actual
[HTML Element] Object and all its descendants contain or match expected textualcontent
content
must be of type [String] or [RegEx]- if
actual
contains multiple of [HTML Text] descendants, it is normalized (empty [HTML Text] nodes and multi spaces are removed from the text) before being compared with expectedcontent
text - return false if
actual
is not [HTML Element] Object or ifcontent
is not of type [String] or [RegEx] - return false if
actual
does not contain or match the text or regular expression passed incontent
- return true if
actual
contains or matches the text or regular expression passed incontent
- return true regardless
actual
[HTML Element] Object is appended to the DOM or not
to check whether the [HTML Text] Object equals text content, use
toBeHTMLText(content)
with expected textcontent
expect(actual).toBeChildOf(parent)
- check if
actual
[HTML Element] Object or [HTML Text] Object is a children ofparent
[HTML Element] Object - return false if
actual
is not [HTML Element] Object or [HTML Text] Object - return false if
parent
is not [HTML Element] Object - return false if
actual
is not a direct child node ofparent
- return false if
actual
andparent
is the same object - return true if
actual
is the direct child node ofparent
- return true regardless
actual
andparent
are appended to the DOM or not
expect(actual).toBeNthChild(index)
- check if
actual
[HTML Element] Object has expectedindex
in the collection of child nodes ofactual
's parent [HTML Element] Object index
must be of type [Number] equal or greater than0
or of the [String] value:last
expect(actual).toBeNthChild(0)
the matcher checks ifactual
is the first child node of its parentexpect(actual).toBeNthChild(1)
the matcher checks ifactual
is the second child node of its parentexpect(actual).toBeNthChild('last')
the matcher checks ifactual
is the last child node of its parent- it ignores [HTML Text] and [HTML Comment] Objects when getting the collection od child nodes
- return false if
actual
is not [HTML Element] Object - return false if
index
is not of type [Number] greater than 0 or if is not of'last'
value - return false if
actual
is not at expectedindex
inside its [HTML Element] parent - return false if
actual
has not got [HTML Element] parent - return true if
actual
is at expectedindex
inside its [HTML Element] parent - return true regardless
actual
and its [HTML Element] parent are appended to the DOM or not
expect(actual).toBeParentOf(child)
- check if
actual
[HTML Element] Object is a parent ofchild
[HTML Element] Object or [HTML Text] Object - return false if
actual
is not [HTML Element] Object - return false if
child
is not [HTML Element] Object or [HTML Text] Object - return false if
actual
is not a direct parent node ofchild
- return false if
actual
andchild
is the same object - return true if
actual
is the direct parent node ofchild
- return true regardless
actual
andchild
are appended to the DOM or not
expect(actual).toHaveSameParent(node)
- check if
actual
andnode
are the children of the same [HTML Element] Object actual
andnode
must be of type [HTML Element] or [HTML Text]- return false if
actual
ornode
is not [HTML Element] or [HTML Text] Object - return false if
actual
andnode
are not the children of the same [HTML Element] Object - return true if
actual
andnode
are the children of the same [HTML Element] Object - return true regardless
actual
andnode
are appended to the DOM or not
expect(actual).toHaveChildren(numOfChildren,operator)
- check if
actual
[HTML Element] Object contains any [HTML Element] child nodes - it ignores [HTML Text] and [HTML Comment] Objects
numOfChildren
is optional, if passed must be of type [Number] equal or greater than0
numOfChildren
, if passed the matcher checks if the number ofactual
child nodes equals to expectednumOfChildren
- if
numOfChildren
is not of type [Number] or is less than0
, it is ignored as if it was not passed operator
is optional, if passed must be the one of following [String] values:or more
,or less
,more than
,less than
expect(actual).toHaveChildren(3)
the matcher checks ifactual
has got 3 element nodesexpect(actual).toHaveChildren(3,'or more')
the matcher checks ifactual
has got 3 or more than 3 element nodesexpect(actual).toHaveChildren(3,'or less')
the matcher checks ifactual
has got 3 or less than 3 element nodesexpect(actual).toHaveChildren(3,'more than')
the matcher checks ifactual
has got more than 3 element nodesexpect(actual).toHaveChildren(3,'less than')
the matcher checks ifactual
has got less than 3 element nodes- if
operator
is not the one of indicated four values, it is ignored as if it was not passed - return false if
actual
is not [HTML Element] Object - return false if
actual
does not contain any [HTML Element] child nodes (ifnumOfChildren
not passed) - return false if
actual
does not contain expected number of [HTML Element] child nodes (ifnumOfChildren
|operator
passed) - return true if
actual
contains at least one [HTML Element] child node (ifnumOfChildren
not passed) - return true if
actual
contains expected number of [HTML Element] child nodes (ifnumOfChildren
|operator
passed) - return true regardless
actual
[HTML Element] Object is appended to the DOM or not
expect(actual).toBeNextSiblingOf(expected)
- check if
actual
[HTML Element] Object is the next element sibling ofexpected
[HTML Element] Object - both
actual
andexpected
must be of type [HTML Element] - it ignores [HTML Text] and [HTML Comment] sibling Objects
- return false if
actual
orexpected
is not [HTML Element] Object - return false if
actual
is not the next element sibling ofexpected
- return false if
expected
has not got any next element sibling - return true if
actual
is the next element sibling ofexpected
- return true regardless
actual
andexpected
is appended to the DOM or not
expect(actual).toBePreviousSiblingOf(expected)
- check if
actual
[HTML Element] Object is the previous element sibling ofexpected
[HTML Element] Object - both
actual
andexpected
must be of type [HTML Element] - it ignores [HTML Text] and [HTML Comment] sibling Objects
- return false if
actual
orexpected
is not [HTML Element] Object - return false if
actual
is not the previous element sibling ofexpected
- return false if
expected
has not got any previous element sibling - return true if
actual
is the previous element sibling ofexpected
- return true regardless
actual
andexpected
is appended to the DOM or not
expect(actual).toBeEmpty()
- check if
actual
[HTML Element] Object has not got any [HTML Element] or [HTML Text] child nodes - it ignores [HTML Comment] Objects, empty text nodes, <br/> and <wbr/> tags
- return false if
actual
is not [HTML Element] Object - return false if
actual
contains at least one [HTML Element] Object or [HTML Text] Object - return true if
actual
has not got any [HTML Element] or [HTML Text] descendant - return true regardless
actual
[HTML Element] Object is appended to the DOM or not
the difference between .toBeEmpty() matcher and .toHaveChildren() matcher is that .toBeEmpty() matcher checks if the actual [HTML Element] Object contains both [HTML Element] and [HTML Text] Objects when .toHaveChildren() matcher checks if the actual [HTML Element] Object contains only [HTML Element] Objects.
expect(actual).toHaveAnyAttribute()
- check if
actual
[HTML Element] Object has got any attribute defined - return false if
actual
is not [HTML Element] Object - return false if
actual
is has not got any attribute defined - return true if
actual
is has got at least one attribute defined
expect(actual).toHaveAttribute(name,value)
- check if
actual
[HTML Element] Object has expected attributename
of expectedvalue
name
must be of type [String]value
parameter is optional, if not passed, matcher checks ifactual
has expected attributename
regardless its valuevalue
parameter if passed, must be of type [String] or of type [RegExp]- if
value
is not of type [String] or of type [RegExp], it is ignored as if it was not passed (matcher checks ifactual
has expected attributename
regardless its value) - if the
value
is of type [String] the matcher checks the equality of attribute's value and expectedvalue
- if the
value
is of type [RegExp] the matcher useString.prototype.match()
to check if the attribute's value matches the expected regular expressionvalue
- return false if
actual
is not [HTML Element] Object or ifname
is not of type [String] - return false if
actual
does not have expected attributename
(ifvalue
not passed) - return false if
actual
does not have expected attributename
of expectedvalue
(ifvalue
passed) - return true if
actual
has expected attributename
(ifvalue
not passed) - return true if
actual
has expected attributename
of expected valuevalue
(ifvalue
passed) - return true regardless
actual
is appended to the DOM or not
with appropriate /regular expression/ passed as
value
parameter it is possible to check whether class attribute contains expected class, but it is easier to achieve with .toHaveClass() custom matcher
expect(actual).toHaveClass(class)
- check if
actual
[HTML Element] Object has got class attribute with expected valueclass
from among the list of classes class
must be of type [String]- return false if
actual
is not [HTML Element] Object or ifclass
is not of type [String] - return false if
actual
has not got expectedclass
set - return true if
actual
has got expectedclass
set - return true regardless
actual
is appended to the DOM or not
to check whether [HTML Element] Object has got a class attribute defined regardless its values, use
.toHaveAttribute('class')
matcher
expect(actual).toHaveComputedStyle(prop,value)
- check if
actual
[HTML Element] Object's computedprop
style is of expectedvalue
actual
must be appended into the DOM tree, so that the [CSSStyleDeclaration] Object could be returnedprop
must be of type [String] (both camelCase and hyphen-case are accepted)value
must be of type [String] or [RegExp]- if the
value
is of type [String] the matcher checks the equality of the computed style's value and expectedvalue
- if the
value
is of type [RegExp] the matcher useString.prototype.match()
to check if the computed style's value matches the expectedvalue
regular expression - return false if
actual
is not [HTML Element] Object orprop
is not of type [String] orvalue
is not of type [String] or [RegExp] - return false if returned [CSSStyleDeclaration] Object has not contain
prop
property - return false if
actual
has got the computedprop
style of the different value than expectedvalue
- return true if
actual
has got the computedprop
style of the same value as expected [String]value
or if computedprop
style matches expected [RegExp]value
in order to deal with the differences between browsers of returning computed style values, use regular expression
.toHaveComputedStyle('propertyName',/(ms-value|moz-value|webkit-value)/)
expect(actual).toHaveComputedColor(prop,value)
- check if
actual
[HTML Element] Object's computedprop
style is of expectedvalue
- the difference between
toHaveComputedStyle()
andtoHaveComputedColor()
is thattoHaveComputedColor()
is convenient to compare each CSS*-color
property, which demand or return color value (background-color
,border-bottom-color
,color
,box-shadow
,text-shadow
,outline-color
, etc.) - the convenience is that you can expect the color
value
in the format of your choice (#HEX
RGB()
orHSL()
), regardless which format the browser return as computed actual
must be appended into the DOM tree, so that the [CSSStyleDeclaration] Object could be returnedprop
must be of type [String] (both camelCase and hyphen-case are accepted)value
must be of type [String] (in order to use [RegExp] value, use matchertoHaveComputedStyle('colorProp',/regEx/)
)- return false if
actual
is not [HTML Element] Object orprop
is not of type [String] orvalue
is not of type [String] - return false if returned [CSSStyleDeclaration] Object has not contain
prop
property - return false if
actual
computedprop
style does not match expectedvalue
color - return true if
actual
computedprop
style matches expectedvalue
color
If the browser return
rgb(255, 255, 0) 2px 2px 2px
as computed 'box-shadow' style, the expectedvalue
rgb(255, 255, 0)
,rgba(255, 255, 0, 1)
,#ff0
,#FFFF00
,hsl(60, 100%, 50%)
andhsla(60, 100%, 50%, 1)
will return truthy result.
If the browser return
rgba(255, 255, 0, .4)
as computed 'color' style, the expectedvalue
rgba(255, 255, 0, .4)
andhsla(60, 100%, 50%, .4)
will return truthy result.
If the browser return
rgba(255, 255, 0, .4)
as computed 'color' style, the expectedvalue
rgb(255, 255, 0)
,#ff0
,#FFFF00
andhsl(60, 100%, 50%)
will return faulty result because the alpha parameter does not match.
Because of the differences between browsers, the
alpha
parameter ofhsla()
andrgba()
formats is rounded to two digits after decimal point. The same result will be aimed withrgba(100, 100, 100, 0.23)
,rgba(100, 100, 100, 0.230445)
,rgba(100, 100, 100, 0.2349999999)
expect(actual).toHaveEvent(event)
- check if
actual
[HTML Element] Object has got expectedevent
attached - it does not detect events attached by
addEventListener()
method - <div onclick='fireClick'></div> this event will be detected
actual.onclick = fireClick
this event will be detectedactual.addEventListener('click',fireClick)
this event will not be detectedevent
must be of type [String] and must indicate expected event name, eg.click
,mouseover
,focuson
,resize
(bothclick
and prefixedonclick
syntax accepted)- return false if
actual
is not [HTML Element] Object orevent
is not of type [String] - return false if
event
is not recognized event name - return false if
actual
has not got expectedevent
attached - return false if
actual
has got expectedevent
attached by theaddEventListener()
method - return true if
actual
has got expectedevent
attached - return true regardless
actual
is appended to the DOM or not
Tips
Each matcher demands accurate type of parameter value. The matcher check the
actual
andexpected
parameters' types before implementing the comparison and return false when value type is incorrect regardless the comparison result.
Compared [HTML Element] and [HTML Text] Objects do not have to be appended to the DOM tree in order to use DOM custom matcher. The comparison can be implemented for dynamically created elements in
beforeEach()
,beforeAll()
orit()
scope. Exception is.toBeDocumentNode()
matcher which check ifactual
Object is appended to the DOM and.toHaveComputedStyle()
.toHaveComputedColor()
matchers which require the [HTML Element] Object to be appended to the DOM in order to return the expected computed style
In order to check whether two HTML Objects are the same objects use the native matcher
expect(objectA).toBe(objectB)
In order to check whether two HTML Objects are equal objects use the native matcher
expect(objectA).toEqual(objectB)
Implementation
with NodeJS
npm install jasmine-dom-custom-matchers --save-dev
var matchers = require('jasmine-dom-custom-matchers'); //get the module
describe("The new DIV element", function() {
beforeAll(function() {
jasmine.addMatchers(matchers); //set custom matchers for jasmine
this.newDiv = document.createElement('DIV');
});
it("should be empty.", function() {
expect(this.newDiv).toBeEmpty(); //do the magic with new DOM matchers
});
}
You can use
karma-html
module to test your.html
files in thekarma
browser runner [git] [npm]
with Karma
Use karma-jasmine-dom
package [link] that adapts the jasmine-dom-custom-matchers
package for karma
.
with Browser
1. Load dom-matchers.js
in html file
<head>
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-core/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-core/jasmine.css">
<script type="text/javascript" src="jasmine/lib/jasmine-core/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-core/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-core/boot.js"></script>
<script type="text/javascript" src="dom-matchers.js"></script>
</head>
Any outer libraries needed. It is a fully JavaScript library.
2. Load custom matchers with jasmine.addMatchers
in your tests files
describe("The new DIV element", function() {
beforeAll(function() {
//DOMCustomMatchers is the global window object got from dom-matchers.js
jasmine.addMatchers(DOMCustomMatchers);
this.newDiv = document.createElement('DIV');
});
it("should be empty.", function() {
expect(this.newDiv).toBeEmpty(); //do the magic with new DOM matchers
});
}
How to use
- visit sample site and consider jasmine passed specs section (you can see how DOM custom matchers can be used)
- consider the HTML source with the login panel sample
- consider the <style> section with CSS styles for login panel
- consider the tests.js source to figure out how matchers were implemented
See also
karma-html
to test your.html
files in thekarma
browser runner [git] [npm]karma-jasmine-dom
package to usejasmine-dom-custom-matchers
with karma [npm]jasmine
custom matchers docs [link]jasmine
installation [link]
License
Released under the MIT license.
Copyright (c) 2017 Paweł Rafałko [email protected]
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.