Test API V2
The following is our complete document for V2 of Tenon's Test API. A complete Postman collection is available to demonstrates all routes.git
General Flow
Tenon's V2 Test API differs significantly from its predecessor in terms of workflow:
- V1 accepts only
POST
requests. The V1 API immediately triggers testing and returns the results on completion of that testing. - In V2,
POST
requests do not immediately trigger testing. Instead, V2 will add successfulPOST
requests to a queue. Doing so allows backend processes to handle the ebb and flow of API traffic to improve system stability during periods of high demand.
As a result, client workflow using V2 should now follow the following general pattern:
- Submit
POST
request to the API. - If the
POST
request was successful, store theresponseID
returned. - Submit
HEAD
requests, looking for an HTTP200
response code - When
HEAD
returns200
, perform aGET
to retrieve the record, using the storedresponseID
as theid
of the record.
Waiting on results
The time necessary to wait to see results depends significantly on a handful of factors - most notable of them is the current queue size. Globally (across millions of test runs), the API takes 3-6 seconds to test a page. However, if the queue is very large, it can take a significantly longer time to test a page.
Client application code should, if possible, make use of the callback
parameter in the initial POST
request. If supplied, the API will submit a POST
to that endpoint with the results of the testing. This approach is strongly preferred over long-polling.
Differences between V1 and V2
Note: this section only mentions the major differences. V2 is, essentially, a completely new system and we cannot catalog all of the differences that will essentially exist.
All changes listed below are discussed further in their relevant sections.
No longer proxied by PHP
- The V1 API is proxied by PHP. This is due to a legacy situation where the Node app did not do the full range of validation that was needed to validate and process responses
- V2 is no longer be proxied by PHP and will handle all routing, authorization, and validation on its own.
V2 is RESTful
- V1 only accepts
POST
requests - V2 is fully RESTful and accepts
GET
,POST
,PUT
,DELETE
, andHEAD
requests.
Changes to Authentication
- V1 authorizes requests based on the use of an API key within the request.
- V2 authenticates users via OAuth. Users must authenticate themselves against the API before submitting further requests against it. The authentication process establishes a Bearer token which must accompany subsequent requests.
Changes to response structure
The response structure for all routes now follows our Tenon Unified API Response Structure:
status
: Numeric Token. HTTP Status code representing the state of your request. Values will be 200, 400, 401, 402, 403, 404, 405, 500, or 522message
: String Token. Human readable text message that corresponds to the numeric HTTP status abovecode
: String Token. A token value that represents the reason for the response.info
: String Token.moreInfo
: String URL. A fully qualified URL at which you can learn more details explaining the reason for the response.responseExecTime
: Float. How long, in seconds, the request took to processresponseTime
: String. Time of your request, localized to GMTresponse
: Object. An object containing the response. Content within this object depends on what type of request it was. The structure of the test results is described in (Test Results Response Structure)[#Test-Results-Response-Structure]
Example from a successful POST
request.
{
"status": 200,
"message": "OK",
"code": "success",
"info": "Accepted",
"moreInfo": "https://www.tenon.io/documentation/apiv2/response-codes#success",
"responseExecTime": 0.255717702,
"responseTime": "2020-09-15T13:36:35.735Z",
"data": {
"responseID": "d5b956a7-e28a-41cf-817c-a0200842a9d0"
}
}
Changes to POST
request
- V1 requests required the request to be sent as
form-data
orx-www-form-urlencoded
. - V2 requests are all made as raw JSON
Addition of context
to testing
- V1 tests whole documents when given a
url
. - V2 allows customers to pass in a special parameter that identifies a specific part of the page as a selector that can be passed to
context
. Whencontext
is provided, the API will limit testing to that part of the page.
Modifications to delay
and waitFor
V1 of the API previously had a confusingly named parameter, waitFor
that operated like a delay. It was renamed to delay
, because the only part we had implemented was a timed delay. However there have been customers who asked for a feature similar to Puppeteer’s waitFor
, in that it waits for a specific event to fire.
Puppeteer’s waitFor
is more robust and is well documented. We’ll pass-through the user’s settings directly to Puppeteer.
Addition of ignore
Only valid in POST
requests, ignore
accepts a comma-delimited list of issue signatures that should be ignored during testing.
Addition of metadata
V2 allows customers to pass in a metadata
object to both POST
and PUT
requests. This object can then be used by their consuming applications for any other arbitrary purpose and allows them to customize information relating to the test run.
Addition of headers
V2 allows customers to pass an object containing key:value
pairs that will then be used by the API during testing. This allows customers greater control over testing, because it will allow the API to send over HTTP Headers as part of its request that can facilitate things like Content Negotiation or Authentication
Addition of cookies
V2 allows customers to pass an array of objects containing cookies that should be set during the request. Because this information will be part of the request(s) to the API, it can also be persisted across multiple requests the API makes even if multiple Puppeteer instances are used in the process
Not tested immediately
- In V1,
POST
requests cause the request to be processed immediately for testing. - V2 adds the request into a test queue instead of testing right away. This will allow customers to submit potentially thousands of requests at once without fear of overloading the system.
Addition of other services
The initial release will integrate with two companion services:
- Source Saver
- Tenon Screenshot
Successful POST
requests to V2 trigger requests for the page to be downloaded via our ‘Source Saver’ service (which saves a copy of the page being tested) and a request for a screenshot of the page to be taken via ‘Tenon Screenshot’. These will be made available via the Tenon.io web UI.
Routes
The following is a full list of all routes supported by V2, their supported parameters, validation, and status responses.
The endpoint for all V2 requests is https://{{domain}}/api/v2/
where domain
is the domain of the Tenon instance. For our SaaS customers, the domain is tenon.io
.
Auth (POST: /api/v2/auth
)
All requests to the API must come from an authenticated user. This is done by sending a POST
request to the authentication endpoint with a username and password and retrieving a token that must be used on future requests.
Example Request
{
"username" : "me@example.com",
"password" : "xyzpdq123@!"
}
Status Codes Returned
HTTP Status Code | Explanation |
---|---|
200 |
The request was valid and the operation was successful |
400 |
One (or more) of the parameters supplied was missing or invalid |
401 |
The user is not authenticated |
500 |
There was a problem on our end and the request could not be processed |
Processing
Upon successful request, a JSON response is returned. Of the returned data, the two most important values are access_token
and expires_in
.
access_token
: This value must be passed through on subsequent requests to the API. It must be passed as theAuthorization
request header in the formBearer {{access_token}}
expires_in
: Represents the total time, in seconds, that the token will remain valid. We advise that your application code should be aware of this time and, if needed, be set to reauthenticate when the token expires.
Sample Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlljM0IzRDBoeTF0bzNZaVA5ZWpSQyJ9.eyJpc3MiOiJodHRwczovL2RlbW8tdGVub25pby5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8MSIsImF1ZCI6Imh0dHBzOi8vZGVtby10ZW5vbmlvLmF1dGgwLmNvbS9hcGkvdjIvIiwiaWF0IjoxNTk4MzYzMzEwLCJleHAiOjE1OTg0NDk3MTAsImF6cCI6IjJwSzNaYUpqOEpKWU1YdXVDQ0ZvbHRUcmE3TmY2YThaIiwic2NvcGUiOiJyZWFkOmN1cnJlbnRfdXNlciB1cGRhdGU6Y3VycmVudF91c2VyX21ldGFkYXRhIGRlbGV0ZTpjdXJyZW50X3VzZXJfbWV0YWRhdGEgY3JlYXRlOmN1cnJlbnRfdXNlcl9tZXRhZGF0YSBjcmVhdGU6Y3VycmVudF91c2VyX2RldmljZV9jcmVkZW50aWFscyBkZWxldGU6Y3VycmVudF91c2VyX2RldmljZV9jcmVkZW50aWFscyB1cGRhdGU6Y3VycmVudF91c2VyX2lkZW50aXRpZXMiLCJndHkiOiJwYXNzd29yZCJ9.DkWJFxSvH164-nCBaozMJiV-OmjbChCwbT84OBrazvHK4EBPc6LQaxp3TGYOwxLT3VZ4TGK7gYbx2eGv1ji7dEWmXiwplhYVnv24flKn2jvOAyqdMcwC9TR76urbMX9Tz0RtdVMUqQ0XjxfHX26MeHYJnwPxKqaMj2BwE6b887nbx14yKMBn7QAqMzs2VihL8mdL9i9wbeGL1Rq7Hv7r4UbnU5R9dxWzaYLIC1Ov2DXttWhioSEG47bheCPHzlwesmiOnjcXMOARYB8by7gfqi3I_cIfkJaIbQcBoMttecvvVDv708F3-2YN9GrN6kakzA3NhnTlSPcMSUyNNaR",
"scope": "read:current_user update:current_user_metadata delete:current_user_metadata create:current_user_metadata create:current_user_device_credentials delete:current_user_device_credentials update:current_user_identities",
"expires_in": 86400,
"token_type": "Bearer"
}
GET
GET
requests retrieve results from the API.
Get All (GET: /api/v2/
)
GET
requests without an id
parameter will return an array of objects representing all requests made against the Test API
Status Codes Returned
HTTP Status Code | Explanation |
---|---|
200 |
The request was valid and the operation was successful |
400 |
One (or more) of the parameters supplied was missing or invalid |
401 |
The user is not authenticated |
500 |
There was a problem on our end and the request could not be processed |
Processing
Upon passing validation, all records retrieved will be returned in the data
object of the response
Optional Parameters
Name | Type | Description |
---|---|---|
limit |
numeric | Represents the maximum number of items to be returned in the result set. If provided, value must be between 0 and '1000' . The default value is 1000 . If invalid, return status:400 and code:"" |
offset |
numeric | Represents the index number from which the limit will begin. If provided, value must be lower than the total number of records available for the user. If invalid, return status:400 and code:"" |
projectID |
string | ID of the project from which to fetch the results. If unspecified, the API will return results from all projects. If invalid, return status:400 and code:"" |
startDate |
string | The first date from which to return results. Required if endDate is supplied. If invalid (or if endDate not supplied), return status:400 and code:"" |
endDate |
string | The last date from which to return results. Required if startDate is supplied. Must be a date after startDate . If invalid (or if startDate not supplied), return status:400 and code:"" |
Understanding limit
and offset
limit
and offset
function the same here as they do in MySQL and PostgreSQL.
More information on limit
and offset
Get By ID (GET: /api/v2/:id
)
When an ID parameter is supplied in the request, the API returns one single result: the response that corresponds to the supplied id
Validation
id
must exist in the request. If not, the API will returnstatus:400
andcode:"required_param_missing"
id
must match theresponseID
of a record that is owned by the user is making the request. If not, the API will returnstatus:404
andcode:"not_found"
- Note: we return
404
here as a security measure. Even if theid
is otherwise valid, if it isn’t owned by the user making the request, it essentially does not exist.
- Note: we return
Status Codes Returned
HTTP Status Code | Explanation |
---|---|
200 |
The request was valid and the operation was successful |
202 |
The request was valid but the test run has not yet been completed (the item is still in queue) |
400 |
One (or more) of the parameters supplied was missing or invalid |
401 |
The user is not authenticated |
404 |
The id provided was not valid or was not owned by the user |
500 |
There was a problem on our end and the request could not be processed |
Processing
Upon passing validation, the retrieved record will be returned in the response
object of the response
HEAD (HEAD: /api/v2/:id
)
A HEAD
request allows the end user to determine whether a resource exists before attempting to perform a GET
request to retrieve the resource.
Validation
id
must exist in the request. If not, the API will returnstatus:400
andcode:"required_param_missing"
id
must match theresponseID
of a record that is owned by the user who is making the request. If not, the API will return If not, returnstatus:404
andcode:"not_found"
- Note: we return
404
here as a security measure. Even if theid
is otherwise valid, if it isn’t owned by the user making the request, it essentially does not exist
- Note: we return
Status Codes Returned
HTTP Status Code | Explanation |
---|---|
200 |
The request was valid and the operation was successful |
202 |
The request was valid but the test run has not yet been completed (the request is still in queue) |
400 |
One (or more) of the parameters supplied was missing or invalid |
401 |
The user is not authenticated |
404 |
The id provided was not valid or was not owned by the user |
500 |
There was a problem on our end and the request could not be processed |
Response
Because this is a HEAD
request, no content will be sent with the response.
POST (POST: /api/v2/
)
POST Request Structure
In V2, POST
requests differ in one important characteristic than V1: in V1, POST
requests must be made as form-data
or as x-www-form-urlencoded
. This is no longer the case for V2 which uses a JSON body.
A successful POST
request will queue testing of the URL or supplied document sourcecode.
HTTP Status Code | Explanation |
---|---|
202 |
The POST request was accepted for processing |
400 |
One (or more) of the parameters supplied was invalid |
401 |
The user is not authenticated |
402 |
The user does not have enough credits available to do testing |
415 |
The user has attempted to test a URL that is not a web page |
429 |
The user has been making too many requests in too short of a period of time |
500 |
There was a problem on our end and the request could not be processed |
Note: in cases where the API returns 429
, the API will also return a retry-after
header with a numeric value indicating the number of seconds to wait before retrying the requests. The retry-after
has a default value of 30
Required Parameters
Parameter | Type | Description |
---|---|---|
url or src |
String | Only one is required. url must be a full-qualified URL to a publicly available URL to be tested. src must be a payload containing only HTML/ CSS/ JS. |
Optional Parameters
Additional parameters can be passed in the POST
body to add specificity to the testing or to override the settings that have been stored in the corresponding project.
Parameter | Type | Description |
---|---|---|
src |
String | Required if url not provided. It must be a payload of HTML/ CSS/ JS source to be tested |
pageTitle |
String | Title of the page. If not provided, the API will retrieve it during processing. |
context |
String | String representing a DOM node that can be used in document.querySelector() to select a specific portion of a page to be tested |
level |
String | WCAG Level to be used for testing. Must be one of A , AA , or AAA . If not supplied, will default to the value stored in the corresponding project. |
certainty |
Numeric | Filter. Minimum certainty score for issues in the resultset . Valid values must be one of 0 ,20 ,40 ,60 ,80 ,100 . If not supplied, will default to the value stored in the corresponding project. |
priority |
Numeric | Filter. Valid values must be one of 0 ,20 ,40 ,60 ,80 ,100 . If not supplied, will default to the value stored in the corresponding project. |
docID |
String | User-supplied string allowing the user to provide a meaningful ID for the document being tested. |
projectID |
String | If not supplied, will default to the user’s default project. |
viewportHeight |
Numeric | If not supplied, will default to the value stored in the corresponding project. |
viewportWidth |
Numeric | If not supplied, will default to the value stored in the corresponding project. |
store |
Boolean | If not supplied, will default to the value stored in the corresponding project. |
appID |
String | User-supplied string documenting the application from which the request was made. |
waitFor |
String | If not supplied, will default to the value stored in the corresponding project. |
ignore |
String | A comma-delimited list of issue signatures that must be ignored during testing |
metadata |
Array/ Object | Object conveying custom key:value pairs that the customer can use to add additional information to their records. If not supplied, will default to the value stored in the corresponding project. |
headers |
Array / Object | Array of objects conveying custom key:value pairs that the customer can use for their own consumption. If not supplied, will default to the value stored in the corresponding project. |
cookies |
Array/ Object | Array of objects conveying the necessary cookie details that the customer can use to pre-set cookies for use in testing. Each object must contain the following keys: name , value , host , path , expires , secure , and HttpOnly , and must conform to RFC 6265 |
callback |
Object | The callback object allows you to define a URL, method, and headers that we will use to send you results of your POST requests.
|
POST Request Validation
User must be authenticated
- If the user is not authenticated, the API returns
status:401
andcode:"api_credentials_invalid"
- The account owner must have > 0 API calls available
- This is the only route that requires the user to have API calls available.
- If the user does not have API calls available, the API will return
status:402
andcode:"payment_required"
url
: Required if src
not supplied
- If supplied, it must be a URL that returns HTTP status
200
. - If the URL does not return HTTP status
200
, the API will returnstatus:400
andcode:"url_request_failed"
and log the URL’s status code in the response. This also includes3xx
responses. The user must be responsible for supplying the final URL as the API will not follow redirects.
src
: Required if url
not supplied
- Must not be supplied if
url
supplied.- Supplying both
url
andsrc
will result in the API returningstatus:400
andcode:"invalid_param"
- Supplying both
- Must be markup.
- If not, the API will return
status:400
andcode:"improper_content_type"
- If not, the API will return
context
- If supplied, must be a valid selector that can be passed to
document.querySelector()
- If
document.querySelector(context)
returnsnull
during testing, the API will returnstatus:400
andcode:"context_not_found"
- If
pageTitle
- If supplied, it must be a string greater than
0
characters- If empty or if
typeOf
not a string, the API will returnstatus:400
andcode:"invalid_param"
- If empty or if
- The API will accept any
pageTitle
length, but will only store the first 255 characters - If not supplied, the API will attempt to retrieve it from the DOM during testing.
level
- If supplied, must be one of
A
,AA
, orAAA
. - If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
certainty
- If supplied, must be one of
0
,20
,40
,60
,80
,100
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
priority
- If supplied, must be one of
0
,20
,40
,60
,80
,100
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
docID
- If supplied, must be a string with no whitespace characters
- The only non-alphanumeric characters allowed are
-
and_
- String length must be greater than 0 characters and less than 255 characters.
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
projectID
- If supplied, must be a UUID
- If supplied, must be a
projectID
for a project owned by the user making the request. - If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
viewPortHeight
- If supplied, must be numeric
- No additional validation necessary
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
viewPortWidth
- If supplied, must be numeric
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
store
- If supplied, must be boolean
- If
typeOf
store
is not boolean, the API will returnstatus:400
andcode:"invalid_param"
appID
- Must be a string greater than
0
characters and less than255
characters in length.- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
- If parameter out of bounds, the API will return
waitFor
- Must be a string greater than
0
characters and less than255
characters in length. - If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
metadata
- Must be an object
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
headers
- Must be an object
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
ignore
- Must be a comma-delimited list of alphanumerics (md5s)
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
callback
- NOTE:
callback
url is not validated in any way
Processing
Upon Request
- The API validates the request according to the rules described above.
- The API generates a UUID to represent the
responseID
- If
src
was supplied, it will:- Automagically detect if the
src
is a fragment - Save the
src
to file. That file will be accessible to the Test API via a fully qualified URL. This will, in turn, become the finalurl
that is tested.
- Automagically detect if the
- The API validates that the user has enough API calls available (NOTE:
POST
requests are the only requests where the Test API validates that the user has API calls available) - The API validates the URL’s MIME type
Upon Passing Validation
- The API sends a request to
tenon-screenshot
to take a screenshot of the page being tested - The API sends a request to
tenon-sourcesaver
to save the page source and all assets for storage - The API forwards the request to
tenon-queue
for processing.
Upon entering the request into the queue.
The API responds to the request with a responseID
with which the user can retrieve results via GET
, PUT
, and HEAD
request types.
PUT (PUT: /api/v2/:id
)
PUT
requests are severely limited in what they can do in Tenon’s Test API. POST
requests initiate testing of a URL with a specific set of configuration parameters and are considered a snapshot of the URL at a specific point in time under the specific request parameters. Therefore, the PUT
request can only modify:
docID
pageTitle
projectID
metadata
Validation
- Validation for those parameters is identical to their validation when they’re included in
POST
requests - Given that
PUT
requests are meant to update a specific record, the request must also contain anid
parameter. id
must exist in the request. If not, the API will returnstatus:400
andcode:"required_param_missing"
id
must match theresponseID
of a record that is owned by the user who has made the request. If not, the API will returnstatus:404
andcode:not_found
- If supplied, the
projectID
parameter must be aprojectID
for a project owned by the owner of the suppliedkey
- If parameter out of bounds, the API will return
status:400
andcode:"invalid_param"
- If parameter out of bounds, the API will return
Status Codes Returned
HTTP Status Code | Explanation |
---|---|
200 |
The request was valid and the operation was successful |
400 |
One (or more) of the parameters supplied was missing or invalid |
401 |
The user is not authenticated |
404 |
The id provided was not valid or was not owned by the user |
500 |
There was a problem on our end and the request could not be processed |
Processing
Once validation has passed, the corresponding record is updated using the new information and the API responds with the full record in the data
object as if this was a GET by ID
request.
DELETE (DELETE: /api/v2/
)
DELETE
requests are made by users who wish to remove a record. Records can only be deleted one at a time.
DELETE
Validation
id
must exist in the request. If not, the API will returnstatus:400
andcode:"required_param_missing"
id
must match theresponseID
of a record that is owned by the user who has made the request. If not, the API will returnstatus:404
andcode:not_found
- Note: we return
404
here as a security measure. Even if theid
is otherwise valid, if it isn’t owned by the user making the request, it essentially does not exist
- Note: we return
Status Codes Returned
HTTP Status Code | Explanation |
---|---|
200 |
The request was valid and the operation was successful |
400 |
One (or more) of the parameters supplied was missing or invalid |
401 |
The user is not authenticated |
404 |
The id provided was not valid or was not owned by the user |
500 |
There was a problem on our end and the request could not be processed |
Processing
Once validation has passed, processing the request will cause the record and all other associated information relating to the record will be deleted.
Test Results Response Structure
The results from accessibility testing can be retrieved only through a GET by id
request. As described in Changes to response structure, the data
object will contain the relevant data for the response. In the case of a GET by id
the data
object will contain the following information.
(Explanation follows the code example)
{
"apiErrors": [],
"documentSize": 113805,
"globalStats": {
"errorDensity": "145",
"warningDensity": "11",
"allDensity": "156",
"stdDev": "375"
},
"resultSet": [
{
"bpID": 106,
"certainty": 100,
"errorDescription": "Link found which contains no text. Because Accessibility APIs use a link's text do determine its accessible name, this link will have no name and will not be announced by assistive technologies.",
"errorSnippet": "",
"errorTitle": "Blank link text found",
"position": {
"column": 71,
"line": 24
},
"priority": 100,
"ref": "https://tenon.io/bestpractice.php?bpID=106&tID=57",
"resultTitle": "Ensure link text (and alternate text for images, when used as links) describes the destination or purpose of the link.",
"signature": "18c1e927a023f074aa9dce6df3092e51",
"standards": [
"Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 2.4.4 Link Purpose (In Context)",
"Web Content Accessibility Guidelines (WCAG) 2.0, Level AAA: 2.4.9 Link Purpose (Link Only)"
],
"tID": 57,
"xpath": "/html/body/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[2]/div[1]/a[1]"
},
],
"resultSummary": {
"density": {
"allDensity": 5,
"errorDensity": 5,
"warningDensity": 0
},
"issues": {
"totalErrors": 6,
"totalIssues": 6,
"totalWarnings": 0
},
"issuesByLevel": {
"A": {
"count": 5,
"pct": 83.33
},
"AA": {
"count": 1,
"pct": 16.67
},
"AAA": {
"count": 1,
"pct": 16.67
}
},
"tests": {
"failing": 6,
"passing": 50,
"total": 56
}
},
"sourceHash": "605ce048930a2c07bbac7255b8fe5de8",
"urlHttpCode": 200,
"clientScriptErrors": [],
"log": []
}
apiErrors
: This array will list out any errors on the Tenon API itself. We hope that this array is always empty. However, if you do see anything here, we’d appreciate it if you’d pass on the following additional information in this section. Each item in the list will include:line
message
sourceId
tID
documentSize
: size, in bytes of the document you gave us to testglobalStats
: The global stats object exists to allow you to compare your document against others that have been tested. Global Stats are a calculation of all tested documents. These stats relate only to “density” - that is, per KB of code, what percentage contain accessibility issues.allDensity
: Density, as a percentage, of both errors and warningserrorDensity
: Density, as a percentage, of errors onlywarningDensity
: Density, as a percentage, of warnings onlystdDev
: Standard Deviation
resultSet
: An array of issue objects. Issue objects are described at https://tenon.io/documentation/understanding-issue-reports.phpresultSummary
: The resultSummary object provides a high level overview of our test results.density
: As mentioned above inglobalStats
the density is a calculation of the issue density in your tested documentallDensity
errorDensity
warningDensity
issues
: This is a count of the issues in your documenttotalErrors
totalIssues
totalWarnings
issuesByLevel
: This is a count of the issues in your document, separated out by WCAG Level. Each level has acount
and apct
tests
: this is a count of how many tests Tenon API ran (total), how many passed, how many failed, and how many total tests were run
sourceHash
: an MD5 hash of the source for the page that was testedurlHttpCode
: The HTTP status code returned by the URL we were given to testclientScriptErrors
: an array that includes any errors on the tested page that may impact Tenon’s ability to test the pagemessage
: The exception messagestacktrace
: This is a full stack trace of the errorfile
: the file where the error existsline
: the line where the error existsfunction
: the function where the error exists
log
: An array of messages piped to the log that may assist in debugging any errors that occurred during testing