Here you can learn how to get 100% of the detest library power. Check out the API including all the test types. For a live example visit detest example.
All the tests options are configured using a yaml
format (usually in a detest.yaml
file). It should be easy to read for anyone but if you need more guidance, check out YAML tutorial.
These settings have effect on all test scenarios. You can always override them using CLI or local settings.
type: String
You can specify name for all test cases. This is for display/organization purpose only and will be shown in test output.
name: Design testing of local app
type: String
You must specify the tested web application starting point. This is required for detest to work correctly.
url: localhost:3000
# or
url: https://www.youtube.com
type: Boolean
You can turn on this flag in order to see the debug logs which might help you find out the reason for tests failure.
debug: True
type: Number
You can specify the timeout (in milliseconds) for puppeteer methods. Defaults to 15000ms
.
timeout: 5000
Using Command Line Interface you can set (or override) any of the global settings options:
detest -u localhost:3000 --debug
Additionally, you specify the detest configuration file name (defaults to detest.yaml
):
detest -c another-set-of-tests.yaml
If you need more information, use the -h
or --help
option:
detest -h
In this section you specify the actual test suites that detest
library should run on your web application. You start it with the tests:
keyword and follow with the array of test scenarios. Each of the test suites has its type
, set of local settings
and usually array of test-cases
to run.
tests:
- name: Home page on desktop
type: styles
test_cases:
- selector: ".App"
text-align: center
display: block
# ...
- name: Home page on mobile
type: layout
width: 375
run: False
test_cases:
# ...
For each test suite you can override any of the global settings. In addition you can specify:
type: String
You can use relative paths to create url for specific test scenario:
url: "/pricing"
# will resolve to localhost:3000/pricing
# if global url is localhost:3000
type Boolean
You can set it to False
in order to omit this test suite. It's useful for debugging & tdd approach.
run: False
type: Number
Browser width size (in px) that the Puppeteer will use when running this test scenario. Especially useful for testing RWD of your web application.
width: 375
type: Number
Browser height size (in px) that the Puppeteer will use when running this test scenario.
height: 800
For each test scenario you specify its type
. Each of them is followed by test_cases
where you can write your test cases using a proper API (according to the test type). Different test types are used for various purposes, so check out their descriptions below.
- type: styles
test_cases:
- selector: ".App"
color: "#fafafa"
This test type is meant to check if:
- specific elements exist on the page
- elements visible styles match design expectations
Each of the test_case
has following attributes:
type: String
Allows you to identify the html page element you want to test. Anything that works for document.querySelector()
function will work here.
type: String
Alternative way to identify the tested element. However, the selector (if passed) is always preferred to xpath.
type: String | Number
Then you specify any style you expect the tested element to have. Detest will verify the actual, styles visible on the page, not these that are put in css files.
Example:
test_cases:
- selector: ".App"
text-align: center
display: block
- selector: "#root > div > div > img"
color: "rgb(255,255,255)"
- xpath: '//*[@id="root"]/div/div'
background-color: "#282c34"
width: "1600px"
color: white
This test type is meant to check if:
- specific element can be found on exact (x,y) position on the page
- there is a correct number of specific elements on the page (or inside another element e.g. header)
Each of the test_case
has following attributes:
Same role as here.
type: { x: Number, y: Number }
Optional: Verify if the element is visible on the page, on position (x, y).
type: Array<{ selector/xpath: String, count?: Number }>
Optional: It checks if each of elements in the array (identified either by selector or xpath) is presented count
times within the main element. If count
is omitted, it's set to 1 by default.
Example:
test_cases:
- selector: header
position:
x: 0
y: 20
contains:
- selector: a
count: 3
- selector: .MuiTypography-h6
- selector: main
contains:
- selector: .MuiCard-root
count: 3
This test types allow you to automatically verify your web application design, without specifying any test-cases
. However, their local settings API is the same as for normal test types.
This test type is meant to validate contrast ratio of all the text elements on the page according to WCAG2.0.
- name: Test contrast ratio for pricing page
type: contrast
url: /pricing
The final output includes:
- Test names
INFO [2021-09-22 20:58:39.874 +0200]: Starting test case suite: Home page on desktop
- Information of each test case evaluation
# Subtest: [STYLES SERVICE]: Checking element: .App
ok 1 - check if element .App exists
ok 2 - compare if element .App styles match
1..2
ok 1 - [STYLES SERVICE]: Checking element: .App # time=11.157ms
- Debug logs (if
debug: True
)
DEBUG [2021-09-22 21:03:06.745 +0200]: Returning browser reference as its already launched
- Tests summary
TESTS SUMMARY
TOTAL TEST CASES RUN:
88
TOTAL TEST CASES PASSED:
88
TOTAL TEST CASES FAILED:
0
SUCCESS RATIO
100.00%
In case of test failure you will see the difference between expectations and actual value found on the page:
not ok 2 - compare if element .App styles match
---
diff: |
--- expected
+++ actual
@@ -1,4 +1,4 @@
Object {
"text-align": "center",
- "display": "inline",
+ "display": "block",
}
In this case, we expected display: inline
but display: block
was found instead.
A couple of utilities that might help you in everyday test writing.
Applies for test types: styles, layout
New attributes: inside
, isDirectChild
Suppose that you have following html structure:
<div id="free">
<div class="MuiCardHeader-root">...</div>
<div class="MuiCardHeader-content">
<h2>$0</h2>
<div>
<div>
<button>Sign up for free</button>
</div>
</div>
then instead of repeating the #free
selector everytime like this:
- selector: "#free"
height: 332
- selector: "#free > .MuiCardHeader-root"
padding: 16
background-color: "#eee"
- selector: "#free h2"
font-size: 48
font-family: "Roboto, Helvetica, Arial, sans-serif"
- selector: "#free button"
color: "#3f51b5"
you can use the inside
attribute to test all descendant of #free
element like this:
- selector: "#free"
height: 332
inside:
- selector: ".MuiCardHeader-root"
isDirectChild: True
padding: 16
background-color: "#eee"
- selector: "h2"
font-size: 48
font-family: "Roboto, Helvetica, Arial, sans-serif"
- selector: "button"
color: "#3f51b5"
The isDirectChild
(defaults to False
) specifies that an element is direct child of its parent. In case of selector it's equivalent to : $parentSelector > $childSelector
.
You can also nest xpath
in the same way as selector
!
Nesting level is not limited to one, you can nest your tests how many times you want!
Detest has additional support for following UI components frameworks/libraries:
If you are using one of them, you can specify it in the global config:
global:
# ...
UI_framework: material
# or
# UI_framework: bootstrap
Now instead of specifying a detailed selector/xpath for every element you would like to test, you can use the component name (camel cased) and it will be automatically mapped to a proper selector.
Example:
- name: Pricing tab on desktop
type: styles
test_cases:
- selector: "bar"
width: 1600
height: 64
background-color: "#3f51b5"
- selector: "#pro"
height: 356
inside:
- selector: "cardHeader"
padding: 16
background-color: "#eee"
- name: Welcome page layout desktop
type: layout
test_cases:
- selector: main
contains:
- selector: "outlinedInput"
count: 2