Introduction
Parrot QA is the easiest way to test your website.
We tried to make our API easy, too.
It is RESTful, and generally conforms to the JSON API spec.
Authentication
Don’t forget to replace
42
with your Org ID andabcdefghij0123456789
with your Token!
require 'net/http'
require 'json'
uri = URI.parse("https://www.parrotqa.com/v1/orgs/42/recordings")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Token abcdefghij0123456789"
response = http.request request
parsed = JSON.parse(response.body)
end
curl -H "Authorization: Token abcdefghij0123456789" \
https://www.parrotqa.com/v1/orgs/42/recordings
To get started with an API Token, simply shoot us an email (hey at parrotqa.com) and we’ll get you setup pronto!
All requests are nested under your Org ID, for example:
GET https://www.parrotqa.com/v1/orgs/42/recordings
Tokens are passed as a Token
in the Authorization
header, like so:
Token abcdefghij0123456789
All requests must be made over HTTPS
.
Recordings
{
"id": "103",
"type": "recordings",
"attributes": {
"org_id": 42,
"parent_id": null,
"created_at": "2017-03-27T00:59:34.819Z",
"name": "Log In",
"start_url": "https://www.your-website.com/log-in",
"screen_width": 1024,
"status": "passing",
"replay_frequency": "daily",
"replay_minute": 30,
"replay_hour": 8,
"replay_day": 1,
"replay_timezone": "America/Los_Angeles",
"browser_statuses": [
{
"current": "passing",
"browser": "chrome"
},
{
"current": "passing",
"browser": "firefox"
},
{
"current": "passing",
"browser": "safari"
}
]
}
}
Recordings are essentially test scripts. For instance, you might record yourself logging in to your website or buying a widget.
The simplest example is just testing that a page loads, but your Recordings will get more complex as you test the full functionality of your website!
Use the QAmcorder to record your first recording.
Key Attributes
Attribute | Description |
---|---|
name | A semantic and human-readable label |
start_url | The URL where the test script begins |
parent_id | Optional The ID of a recording that should run beforehand to set up the session, like Log In. |
status | Can be pending awaiting expectations testing expectations passing failing running or paused |
browser_statuses | A list of statuses across browsers, where each can be running passing or failing |
screen_width | The browser screen width to test |
replay_frequency | How often the tests should run, can be hourly daily weekly or monthly |
replay_minute | The minute the tests should run, can be 0 through 59 |
replay_hour | The hour the tests should run, can be 0 through 23 |
replay_day | The day of the week or month that the tests should run, can be 0 through 30 |
Create a Recording
require 'net/http'
require 'json'
uri = URI.parse("https://www.parrotqa.com/v1/orgs/42/recordings")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Token abcdefghij0123456789"
request.body = {
start_url: 'https://www.yoursite.com',
validate: true
}.to_json
response = http.request request
parsed = JSON.parse(response.body)
end
curl -s -d '{"start_url":"https://www.yoursite.com","validate":true}' \
-H "Authorization: Token abcdefghij0123456789" \
-H "Content-Type: application/json" \
-X POST https://www.parrotqa.com/v1/orgs/42/recordings
Sample JSON Response
{
"data": {
"id": "103",
"type": "recordings",
"attributes": {
"org_id": 42,
"parent_id": null,
"created_at": "2017-03-27T00:59:34.819Z",
"name": "Navigate to Your Site",
"start_url": "https://www.yoursite.com",
"status": "pending",
"replay_frequency": "daily",
"replay_minute": null,
"replay_hour": null,
"replay_day": null,
"replay_timezone": null,
"browser_statuses": [
{
"current": null,
"browser": "chrome"
},
{
"current": null,
"browser": "firefox"
},
{
"current": null,
"browser": "safari"
}
]
}
}
}
POST https://www.parrotqa.com/v1/orgs/42/recordings
This endpoint creates a new Recording under an Org, which navigates to start_url
you pass.
List your Recordings
require 'net/http'
require 'json'
uri = URI.parse("https://www.parrotqa.com/v1/orgs/42/recordings")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Token abcdefghij0123456789"
response = http.request request
parsed = JSON.parse(response.body)
end
curl -H "Authorization: Token abcdefghij0123456789" \
https://www.parrotqa.com/v1/orgs/42/recordings
Sample JSON Response
{
"data": [
{
"id": "103",
"type": "recordings",
"attributes": {
"org_id": 42,
"parent_id": null,
"created_at": "2017-03-27T00:59:34.819Z",
"name": "Log In",
"start_url": "https://www.your-website.com/log-in",
"screen_width": 1024,
"status": "passing",
"replay_frequency": "daily",
"replay_minute": 30,
"replay_hour": 8,
"replay_day": 1,
"replay_timezone": "America/Los_Angeles",
"browser_statuses": [
{
"current": "passing",
"browser": "chrome"
},
{
"current": "passing",
"browser": "firefox"
},
{
"current": "passing",
"browser": "safari"
}
]
}
},
{
"id": "104",
"type": "recordings",
"attributes": {
"org_id": 17,
"parent_id": 103,
"created_at": "2017-03-25T17:04:37.343Z",
"name": "Buy a Widget",
"start_url": "https://www.your-website.com/buy-a-widget",
"screen_width": 1024,
"status": "passing",
"replay_frequency": "daily",
"replay_minute": 30,
"replay_hour": 8,
"replay_day": 1,
"replay_timezone": "America/Los_Angeles",
"browser_statuses": [
{
"current": "passing",
"browser": "firefox"
},
{
"current": "passing",
"browser": "chrome"
},
{
"current": "passing",
"browser": "safari"
}
]
}
}
]
}
GET https://www.parrotqa.com/v1/orgs/42/recordings
This endpoint retrieves all of the Recordings under an Org.
List Recording Replays
require 'net/http'
require 'json'
uri = URI.parse("https://www.parrotqa.com/v1/orgs/42/recordings/22/replays/chrome")
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new(uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Token abcdefghij0123456789"
response = http.request request
parsed = JSON.parse(response.body)
end
curl -H "Authorization: Token abcdefghij0123456789" \
https://www.parrotqa.com/v1/orgs/42/recordings/22/replays/chrome
Sample JSON Response
{ "data":
[
{
"id": "24862",
"type": "replays",
"attributes": {
"browser": "chrome",
"passed": true,
"ran_at": "2017-03-15T17:57:55.946Z",
"screenshot": "https://parrot-screenshots-production.s3.amazonaws.com/uploads/replay/screenshot/24862/small_random-screenshot.png",
"score": 100,
"recording_id": 22
}
},
{
"id": "24731",
"type": "replays",
"attributes": {
"browser": "chrome",
"passed": true,
"ran_at": "2017-03-14T18:08:39.145Z",
"screenshot": "https://parrot-screenshots-production.s3.amazonaws.com/uploads/replay/screenshot/24731/small_random-screenshot.png",
"score": 90,
"recording_id": 22
}
},
{
"id": "24728",
"type": "replays",
"attributes": {
"browser": "chrome",
"passed": false,
"ran_at": "2017-03-14T17:57:50.880Z",
"screenshot": "https://parrot-screenshots-production.s3.amazonaws.com/uploads/replay/screenshot/24728/small_random-screenshot.png",
"score": 70,
"recording_id": 22
}
}
],
"meta": {
"browser": "chrome",
"recording_id": 22
}
}
GET https://www.parrotqa.com/v1/orgs/42/recordings/22/replays/chrome
If you’d like to get recent screenshots from a Recording, you have to list all the recent Replays.
Update a Recording
require 'net/http'
require 'json'
uri = URI.parse("https://www.parrotqa.com/v1/orgs/42/recordings/22")
req = Net::HTTP::Put.new(uri.path, initheader = {
'Content-Type' => 'application/json',
'Authorization' => 'Token abcdefghij0123456789'
})
req.body = {
replay_frequency: 'daily',
replay_minute: 30,
replay_hour: 8,
replay_timezone: 'America/Los_Angeles',
run_after_save: true,
}.to_json
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request(req)
end
curl -H 'Content-Type: application/json' \
-H "Authorization: Token abcdefghij0123456789" \
-X PUT -d '{"replay_frequency":"daily","replay_minute":30,"replay_hour":8,"replay_timezone":"America/Los_Angeles","run_after_save":true}' \
https://www.parrotqa.com/v1/orgs/42/recordings/22
PUT https://www.parrotqa.com/v1/orgs/42/recordings/22
All Update
endpoints can be reached using PATCH
or PUT
, but they follow the spec for PATCH
in that they only update attributes that are passed.
In other words, you can pass any or all of the following attributes, and only the attributes you pass will be updated:
name
status
parent_id
screen_width
start_url
replay_frequency
replay_minute
replay_hour
replay_day
replay_timezone
You can also pass run_after_save
if you want to run a test immediately.
Run a Test
require 'net/http'
require 'json'
uri = URI.parse("https://www.parrotqa.com/v1/orgs/42/recordings/22/run")
req = Net::HTTP::Post.new(uri.path, initheader = {
'Authorization' => 'Token abcdefghij0123456789'
})
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request(req)
end
curl -H 'Content-Type: application/json' \
-H "Authorization: Token abcdefghij0123456789" \
-X POST https://www.parrotqa.com/v1/orgs/42/recordings/22/run
POST https://www.parrotqa.com/v1/orgs/42/recordings/22/run
To run a one-off test (instead of waiting for the next scheduled replay), simply POST
to the run
endpoint.
Errors
Not all requests are 200 ok! Here are the possible error codes:
Error Code | Meaning |
---|---|
400 | Bad Request – Your request is malformed |
401 | Unauthorized – You passed an invalid token |
404 | Not Found – The specified resource could not be found |
500 | Internal Server Error – We had a problem with our server. Please let us know, or try again later. |
503 | Service Unavailable – We’re temporarily offline for maintenance. Please try again later. |