A Markdown document back — create, update, report
const url = 'https://beta-api.plune.ai/v1/test-cases/markdown';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'text/markdown'}, body: '<!-- test\nid: 6f1c2b3a-0000-4000-8000-0000000000c1\ntype: automated\npriority: high\nstate: draft\nspec: e2e/catalog/search.spec.ts:9\n-->\n## search by sku, the exact match first @smoke @catalog\n\nThe exact match sits first; near matches follow.\n\n<!-- test\ntype: manual\npriority: normal\n-->\n## empty cart says so @cart\n\n## Steps\n\n* Open the cart with nothing in it\n *Expected*: «Your cart is empty» and no checkout button\n'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://beta-api.plune.ai/v1/test-cases/markdown \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: text/markdown' \ --data '<!-- testid: 6f1c2b3a-0000-4000-8000-0000000000c1type: automatedpriority: highstate: draftspec: e2e/catalog/search.spec.ts:9-->## search by sku, the exact match first @smoke @catalog
The exact match sits first; near matches follow.
<!-- testtype: manualpriority: normal-->## empty cart says so @cart
## Steps
* Open the cart with nothing in it *Expected*: «Your cart is empty» and no checkout button'The same document, edited anywhere, read back (D9). Each <!-- test --> block is matched by its id: known — the case is updated (title, texts, priority, body, and its suite when the document has suite blocks); absent — a new draft in the suite of the block it sits under, last; unknown — refused by line. Nothing is deleted: a case or suite the document does not name is not touched. A case’s type never changes this way, and state: is only read back as a warning — states move through their own action. A document with no suite block moves nothing, so a single case pasted back keeps its suite. Suite blocks are matched by id, else by their path — missing segments are created (folders, then the suite), each with a warning. Each write is its own transaction, as in bulk: what was done before a refusal stays done, and the report says which was which. ?dryRun=true gives the same report and writes nothing — plune push shows it before writing.
Format. Testomat’s Classical Tests Markdown Format, verbatim, plus Plune’s columns: <!-- suite --> / <!-- test --> blocks with key: value metadata, the title as the first #/## heading after the block (its @tags are the tags), ## Steps with *Expected*: under each step, <!-- example --> tables. Cases before the first suite block are in no suite; a nested suite is its path in the title, # apps > web > checkout.spec.ts. Plune’s columns: id is the record’s UUID, type may be eval, state is written for the eye and only read back as a warning, spec carries an automated case’s specRef; ## Preconditions, ## Expected result, ## Prompt and ## Assertions (a JSON array) are the body. The full reference: https://docs.plune.ai/platform/cases/markdown/.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters ”Report only; nothing is written, not even the folders of a new path.
Request Body required
Section titled “Request Body required ”Example
<!-- testid: 6f1c2b3a-0000-4000-8000-0000000000c1type: automatedpriority: highstate: draftspec: e2e/catalog/search.spec.ts:9-->## search by sku, the exact match first @smoke @catalog
The exact match sits first; near matches follow.
<!-- testtype: manualpriority: normal-->## empty cart says so @cart
## Steps
* Open the cart with nothing in it *Expected*: «Your cart is empty» and no checkout buttonResponses
Section titled “ Responses ”The report — always, when the body is a document; refusals are inside it.
What a Markdown push did, block by block (D9). Always 200 when the body is a document: refused names each block that could not become a case, with the line it starts on and the reason; warnings are the lines the reader skipped over (a Testomat id, a labels: key, an examples table). With dryRun the same report, nothing written.
object
object
Absent on a dry run for a case that would be created.
1-based line of the <!-- test that opens the block.
object
Absent on a dry run for a case that would be created.
1-based line of the <!-- test that opens the block.
object
Absent on a dry run for a case that would be created.
1-based line of the <!-- test that opens the block.
object
object
object
object
object
Example
{ "dryRun": false, "created": [ { "id": "6f1c2b3a-0000-4000-8000-0000000000c2", "title": "empty cart says so @cart", "line": 12 } ], "updated": [ { "id": "6f1c2b3a-0000-4000-8000-0000000000c1", "title": "search by sku, the exact match first @smoke @catalog", "line": 1 } ], "unchanged": [], "refused": [], "suites": { "created": [], "updated": [] }, "warnings": []}An empty body
object
Example generated
{ "error": "example"}No / invalid token or session
Over 10 MB
object
Example generated
{ "error": "example"}A body that is not text/markdown (or text/plain)
object
Example generated
{ "error": "example"}Rate-limited: either the per-route throttle or a tenant quota. Retry-After carries the seconds until the window rolls over.
object
Example generated
{ "error": "example"}Headers
Section titled “Headers ”Seconds until the window rolls over