api
This commit is contained in:
@ -0,0 +1,35 @@
|
||||
describe("Response tab elements", () => {
|
||||
describe("ModelExample within Operation", () => {
|
||||
it("should render Example tabpanel by default", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.get("#operations-default-addPet")
|
||||
.click()
|
||||
.get("div[data-name=examplePanel]")
|
||||
.first()
|
||||
.should("have.attr", "aria-hidden", "false")
|
||||
})
|
||||
it("should click Schema tab button and render Schema tabpanel for OpenAPI 3", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.get("#operations-default-addPet")
|
||||
.click()
|
||||
.get("button.tablinks[data-name=model]")
|
||||
.first()
|
||||
.click()
|
||||
.get("div[data-name=modelPanel]")
|
||||
.first()
|
||||
.should("have.attr", "aria-hidden", "false")
|
||||
})
|
||||
it("should click Model tab button and render Model tabpanel for OpenAPI 2", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore.swagger.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get("button.tablinks[data-name=model]")
|
||||
.click()
|
||||
.get("div[data-name=modelPanel]")
|
||||
.should("have.attr", "aria-hidden", "false")
|
||||
})
|
||||
})
|
||||
})
|
37
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4442.js
Normal file
37
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4442.js
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("UI #4442: Parameter.content display and execution", function() {
|
||||
it("should display textareas as static documentation according to the `example`", () => {
|
||||
cy.visit("/?url=/documents/bugs/4442.yaml")
|
||||
.get(`#operations-default-get_`)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(
|
||||
`div.json-schema-array > div:nth-child(1) > div > textarea`
|
||||
)
|
||||
.should("have.value", `{\n "userId": 1,\n "currency": "USD"\n}`)
|
||||
.get(
|
||||
`div.json-schema-array > div:nth-child(2) > div > textarea`
|
||||
)
|
||||
.should("have.value", `{\n "userId": 2,\n "currency": "CAD"\n}`)
|
||||
})
|
||||
it("should serialize JSON into a query correctly", () => {
|
||||
cy.visit("/?url=/documents/bugs/4442.yaml")
|
||||
.get(`#operations-default-get_`)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should(
|
||||
"have.text",
|
||||
`http://localhost:3230/?users=${encodeURIComponent(
|
||||
`[{"userId":1,"currency":"USD"},{"userId":2,"currency":"CAD"}]`
|
||||
)}`
|
||||
)
|
||||
})
|
||||
})
|
99
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4641.js
Normal file
99
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4641.js
Normal file
@ -0,0 +1,99 @@
|
||||
const clickTryItOutAndExecute = () => {
|
||||
return cy
|
||||
.get(".btn.try-out__btn") // expand "try it out"
|
||||
.click()
|
||||
.get(".btn.execute") // execute request
|
||||
.click()
|
||||
}
|
||||
|
||||
const fillInApiKeyAndAuthorise = apiKey => () => {
|
||||
return cy
|
||||
.get("section>input") // type api key into input
|
||||
.type(apiKey)
|
||||
.get(".auth-btn-wrapper > .authorize") // authorise button
|
||||
.click()
|
||||
}
|
||||
|
||||
const clickLogoutAndReauthorise = () => {
|
||||
return cy
|
||||
.get(".auth-btn-wrapper button:nth-child(1)") // logout button
|
||||
.click()
|
||||
.get(".auth-btn-wrapper > .authorize") // authorise button
|
||||
.click()
|
||||
}
|
||||
|
||||
describe("#4641: The Logout button in Authorize popup not clearing API Key", () => {
|
||||
beforeEach(() => {
|
||||
cy.server()
|
||||
cy
|
||||
.route({
|
||||
url: "/4641*",
|
||||
response: "OK",
|
||||
})
|
||||
.as("request")
|
||||
})
|
||||
|
||||
it("should include the given api key in requests", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4641.yaml")
|
||||
.get("button.btn.authorize") // open authorize popup
|
||||
.click()
|
||||
.get(".modal-ux-content > :nth-child(1)") // only deal with api_key_1 for this test
|
||||
.within(fillInApiKeyAndAuthorise("my_api_key"))
|
||||
.get(".close-modal") // close authorise popup button
|
||||
.click()
|
||||
.get("#operations-default-get_4641_1") // expand the route details onClick
|
||||
.click()
|
||||
.within(clickTryItOutAndExecute)
|
||||
.wait("@request")
|
||||
.its("request")
|
||||
.then((req) => {
|
||||
expect(req.headers, "request headers").to.have.property("api_key_1", "my_api_key")
|
||||
})
|
||||
})
|
||||
|
||||
it("should not remember the previous auth value when you logout and reauthorise", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4641.yaml")
|
||||
.get("button.btn.authorize") // open authorize popup
|
||||
.click()
|
||||
.get(".modal-ux-content > :nth-child(1)") // only deal with api_key_1 for this test
|
||||
.within(fillInApiKeyAndAuthorise("my_api_key"))
|
||||
.get(".modal-ux-content > :nth-child(1)") // only deal with api_key_1 for this test
|
||||
.within(clickLogoutAndReauthorise)
|
||||
.get(".close-modal") // close authorise popup button
|
||||
.click()
|
||||
.get("#operations-default-get_4641_1") // expand the route details onClick
|
||||
.click()
|
||||
.within(clickTryItOutAndExecute)
|
||||
.wait("@request")
|
||||
.its("request")
|
||||
.then((req) => {
|
||||
expect(req.headers, "request headers").not.to.have.property("api_key_1")
|
||||
})
|
||||
})
|
||||
|
||||
it("should only forget the value of the auth the user logged out from", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4641.yaml")
|
||||
.get("button.btn.authorize") // open authorize popup
|
||||
.click()
|
||||
.get(".modal-ux-content > :nth-child(1)") // deal with api_key_1
|
||||
.within(fillInApiKeyAndAuthorise("my_api_key"))
|
||||
.get(".modal-ux-content > :nth-child(2)") // deal with api_key_2
|
||||
.within(fillInApiKeyAndAuthorise("my_second_api_key"))
|
||||
.get(".modal-ux-content > :nth-child(1)") // deal with api_key_1 again
|
||||
.within(clickLogoutAndReauthorise)
|
||||
.get(".close-modal") // close authorise popup button
|
||||
.click()
|
||||
.get("#operations-default-get_4641_2") // expand the route details onClick
|
||||
.click()
|
||||
.within(clickTryItOutAndExecute)
|
||||
.wait("@request")
|
||||
.its("request")
|
||||
.then((req) => {
|
||||
expect(req.headers, "request headers").not.to.have.property("api_key_1")
|
||||
expect(req.headers, "request headers").to.have.property("api_key_2", "my_second_api_key")
|
||||
})
|
||||
})
|
||||
})
|
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4838.js
Normal file
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4838.js
Normal file
@ -0,0 +1,11 @@
|
||||
import repeat from "lodash/repeat"
|
||||
|
||||
describe("#4838: empty request bodies result in endless loading", () => {
|
||||
it("should render model content changes correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4838.yaml")
|
||||
.get("#operations-Some-post_some_route")
|
||||
.click()
|
||||
.contains("This should be visible")
|
||||
})
|
||||
})
|
19
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4865.js
Normal file
19
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4865.js
Normal file
@ -0,0 +1,19 @@
|
||||
describe("#4865: multiple invocations + OAS3 plugin", () => {
|
||||
it("control: should render the OAS3 badge correctly", () => {
|
||||
// This is a sanity check to make sure the badge is present.
|
||||
// If this is failing, it's probably not related to #4865.
|
||||
cy.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.get("#swagger-ui")
|
||||
.get("pre.version")
|
||||
.contains("OAS3")
|
||||
})
|
||||
|
||||
it("test: should render the OAS3 badge correctly after re-initializing the UI", () => {
|
||||
cy.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.window()
|
||||
.then(win => win.onload()) // re-initializes Swagger UI
|
||||
.get("#swagger-ui")
|
||||
.get("pre.version")
|
||||
.contains("OAS3")
|
||||
})
|
||||
})
|
17
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4867.js
Normal file
17
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4867.js
Normal file
@ -0,0 +1,17 @@
|
||||
describe("#4867: callback parameter rendering", () => {
|
||||
it("should render parameters correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4867.yaml")
|
||||
.get("#operations-default-myOp")
|
||||
.click()
|
||||
.contains("Callbacks")
|
||||
.click()
|
||||
|
||||
.get(".callbacks-container .opblock-summary-path")
|
||||
.should("have.attr", "data-path", "http://$request.query.url")
|
||||
.click()
|
||||
|
||||
.get(".parameters-container")
|
||||
.contains("myParam")
|
||||
})
|
||||
})
|
20
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4943.js
Normal file
20
frontend/web/api-doc/test/e2e-cypress/tests/bugs/4943.js
Normal file
@ -0,0 +1,20 @@
|
||||
describe("#4943: XML example not rendered correctly with oneOf", () => {
|
||||
it("should render integer property correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4943.yaml")
|
||||
.get("#operations-Test-postTest")
|
||||
.click()
|
||||
.get(".microlight")
|
||||
.contains("<b>0</b>")
|
||||
})
|
||||
it("should render oneOf property correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/4943.yaml")
|
||||
.get("#operations-Test-postTest")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".microlight")
|
||||
.contains("<c>\n\t</c>")
|
||||
})
|
||||
})
|
30
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5043.js
Normal file
30
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5043.js
Normal file
@ -0,0 +1,30 @@
|
||||
describe("#5043: path-level $ref path items should inherit global consumes/produces", () => {
|
||||
it("should render consumes options correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5043/swagger.yaml")
|
||||
.get("#operations-pet-findPetsByStatus")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".content-type")
|
||||
.contains("application/json")
|
||||
.get(".content-type")
|
||||
.contains("application/xml")
|
||||
.get(".content-type")
|
||||
.contains("text/csv")
|
||||
})
|
||||
it("should render produces options correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5043/swagger.yaml")
|
||||
.get("#operations-pet-findPetsByStatus")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".body-param-content-type select")
|
||||
.contains("application/json")
|
||||
.get(".body-param-content-type select")
|
||||
.contains("application/xml")
|
||||
.get(".body-param-content-type select")
|
||||
.contains("text/csv")
|
||||
})
|
||||
})
|
15
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5060.js
Normal file
15
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5060.js
Normal file
@ -0,0 +1,15 @@
|
||||
describe("#5060: unwanted smart quotes in rendered Markdown", () => {
|
||||
it("should not convert regular quotes to smart quotes", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5060.yaml")
|
||||
.get("div.description")
|
||||
.should($el => {
|
||||
const text = $el.get(0).textContent
|
||||
expect(text).to.include(`Example of a simple GET request via curl with bearer HTTP Authentication`)
|
||||
expect(text).to.include(`curl -X GET "https://foobar.com/stuff"`)
|
||||
expect(text).to.include(`-H "Accept: application/json"`)
|
||||
expect(text).to.include(`-H "Authorization: Bearer abc123.xyz.789"`)
|
||||
expect(text.indexOf(`“`)).to.equal(-1)
|
||||
})
|
||||
})
|
||||
})
|
32
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5070.js
Normal file
32
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5070.js
Normal file
@ -0,0 +1,32 @@
|
||||
describe("#5070: Required field not highlighted on click of Execute button (second time)", () => {
|
||||
it("should not clear error class=invalid on input field (Swagger)", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore.swagger.yaml")
|
||||
.get("#operations-pet-getPetById")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute without user input
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description input")
|
||||
.should($el => {
|
||||
expect($el).to.have.length(1)
|
||||
const className = $el[0].className
|
||||
expect(className).to.match(/invalid/i)
|
||||
})
|
||||
// Cancel Try It Out
|
||||
.get(".cancel")
|
||||
.click()
|
||||
// Expand Try It Out (Again)
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description input")
|
||||
.should($el => {
|
||||
expect($el).to.have.length(1)
|
||||
const className = $el[0].className
|
||||
expect(className).to.match(/invalid/i)
|
||||
})
|
||||
})
|
||||
})
|
22
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5072.js
Normal file
22
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5072.js
Normal file
@ -0,0 +1,22 @@
|
||||
describe("#5072: x-www-form-urlencoded request body input when `properties` is missing", () => {
|
||||
it("should provide a JSON input for an empty object schema", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/5072/empty.yaml")
|
||||
.get("#operations-default-postObject")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(`.opblock-section-request-body textarea`)
|
||||
.should("have.value", "{}")
|
||||
})
|
||||
it("should provide a JSON input for an additionalProperties object schema", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/5072/additional.yaml")
|
||||
.get("#operations-default-postObject")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(`.opblock-section-request-body textarea`)
|
||||
.contains(`"additionalProp1": "string"`)
|
||||
})
|
||||
})
|
121
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5129.js
Normal file
121
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5129.js
Normal file
@ -0,0 +1,121 @@
|
||||
describe("#5129: parameter required + allowEmptyValue interactions", () => {
|
||||
describe("allowEmptyValue parameter", () => {
|
||||
const opId = "#operations-default-get_aev"
|
||||
it("should omit the parameter by default", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev")
|
||||
})
|
||||
it("should include a value", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters-col_description input[type=text]`)
|
||||
.type("asdf")
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev?param=asdf")
|
||||
})
|
||||
it("should include an empty value when empty value box is checked", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters-col_description input[type=checkbox]`)
|
||||
.check()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev?param=")
|
||||
})
|
||||
it("should include a value when empty value box is checked and then input is provided", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters-col_description input[type=checkbox]`)
|
||||
.check()
|
||||
.get(`.parameters-col_description input[type=text]`)
|
||||
.type("1234")
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev?param=1234")
|
||||
})
|
||||
})
|
||||
describe("allowEmptyValue + required parameter", () => {
|
||||
const opId = "#operations-default-get_aev_and_required"
|
||||
it("should refuse to execute by default", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.wait(1000)
|
||||
.get(".request-url pre")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("should include a value", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters-col_description input[type=text]`)
|
||||
.type("asdf")
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev/and/required?param=asdf")
|
||||
})
|
||||
it("should include an empty value when empty value box is checked", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters-col_description input[type=checkbox]`)
|
||||
.check()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev/and/required?param=")
|
||||
})
|
||||
it("should include a value when empty value box is checked and then input is provided", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/5129.yaml")
|
||||
.get(opId)
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters-col_description input[type=checkbox]`)
|
||||
.check()
|
||||
.get(`.parameters-col_description input[type=text]`)
|
||||
.type("1234")
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.get(".request-url pre")
|
||||
.should("have.text", "http://localhost:3230/aev/and/required?param=1234")
|
||||
})
|
||||
})
|
||||
})
|
10
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5138.js
Normal file
10
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5138.js
Normal file
@ -0,0 +1,10 @@
|
||||
describe("#5138: unwanted `url`/`urls` interactions", () => {
|
||||
it("should stably render the first `urls` entry", () => {
|
||||
cy
|
||||
.visit("/pages/5138/")
|
||||
.get("h2.title")
|
||||
.contains("USPTO Data Set API")
|
||||
.wait(3000)
|
||||
.contains("USPTO Data Set API")
|
||||
})
|
||||
})
|
19
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5164.js
Normal file
19
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5164.js
Normal file
@ -0,0 +1,19 @@
|
||||
describe("#5164: multipart property initial values", () => {
|
||||
it("should provide correct initial values for objects and arrays", () => {
|
||||
const correctObjectValue = JSON.stringify({
|
||||
"one": "abc",
|
||||
"two": 123
|
||||
}, null, 2)
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/5164.yaml")
|
||||
.get("#operations-default-post_")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(`.parameters[data-property-name="first"] textarea`)
|
||||
.should("have.value", correctObjectValue)
|
||||
.get(`.parameters[data-property-name="second"] input`)
|
||||
.should("have.value", "hi")
|
||||
})
|
||||
})
|
18
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5188.js
Normal file
18
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5188.js
Normal file
@ -0,0 +1,18 @@
|
||||
describe("#5188: non-string operation summary value", () => {
|
||||
it("should gracefully handle an object value for an operation summary", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/5188.yaml")
|
||||
.get("#operations-default-objectSummary")
|
||||
.click()
|
||||
.get(".opblock-summary-description")
|
||||
.contains("[object Object]")
|
||||
})
|
||||
it("should gracefully handle a missing value for an operation summary", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/5188.yaml")
|
||||
.get("#operations-default-noSummary")
|
||||
.click()
|
||||
// check for response rendering; makes sure the Operation itself rendered
|
||||
.contains("Invalid input")
|
||||
})
|
||||
})
|
38
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5452.js
Normal file
38
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5452.js
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("#5452: <Select /> crashing in Parameters", function() {
|
||||
describe("in OpenAPI 3", () => {
|
||||
it("should not result in a render error", function() {
|
||||
cy.visit("http://localhost:3230/?url=/documents/bugs/5452/openapi.yaml")
|
||||
.get("#operations-default-get_endpoint")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters > tbody > tr > .parameters-col_description > select")
|
||||
.select("")
|
||||
.get(".parameters > tbody > tr > .parameters-col_description > select")
|
||||
.should("exist")
|
||||
.select("fruit")
|
||||
.get(".parameters > tbody > tr > .parameters-col_description > select")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
describe("in Swagger 2", () => {
|
||||
it("should not result in a render error", function() {
|
||||
cy.visit("http://localhost:3230/?url=/documents/bugs/5452/swagger.yaml")
|
||||
.get("#operations-default-get_endpoint")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters > tbody > tr > .parameters-col_description > select")
|
||||
.select("")
|
||||
.get(".parameters > tbody > tr > .parameters-col_description > select")
|
||||
.should("exist")
|
||||
.select("fruit")
|
||||
.get(".parameters > tbody > tr > .parameters-col_description > select")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
})
|
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5453.js
Normal file
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5453.js
Normal file
@ -0,0 +1,11 @@
|
||||
// http://github.com/swagger-api/swagger-ui/issues/5453
|
||||
|
||||
describe("#5453: Responses w/o `content` should not render ModelExample", () => {
|
||||
it("should not render a ModelExample section", () => {
|
||||
cy.visit("/?url=/documents/bugs/5453.yaml")
|
||||
.get("#operations-default-get_foo")
|
||||
.click()
|
||||
.get(".responses-inner")
|
||||
.should("not.have.descendants", ".model-example")
|
||||
})
|
||||
})
|
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5455.js
Normal file
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5455.js
Normal file
@ -0,0 +1,11 @@
|
||||
// http://github.com/swagger-api/swagger-ui/issues/5455
|
||||
|
||||
describe("#5455: Request bodies w/o `examples` should not render a dropdown", () => {
|
||||
it("should not render a <select> element", () => {
|
||||
cy.visit("/?url=/documents/bugs/5455.yaml")
|
||||
.get("#operations-default-post_foo")
|
||||
.click()
|
||||
.get(".opblock-section-request-body > .opblock-description-wrapper")
|
||||
.should("not.have.descendants", "select")
|
||||
})
|
||||
})
|
22
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5458.js
Normal file
22
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5458.js
Normal file
@ -0,0 +1,22 @@
|
||||
// http://github.com/swagger-api/swagger-ui/issues/5458
|
||||
|
||||
const expectedValue = `{
|
||||
"foo": "custom value"
|
||||
}`
|
||||
|
||||
describe("#5458: Swagger 2.0 `Response.examples` mappings", () => {
|
||||
it("should render a custom example when a schema is not defined", () => {
|
||||
cy.visit("/?url=/documents/bugs/5458.yaml")
|
||||
.get("#operations-default-get_foo1")
|
||||
.click()
|
||||
.get(".model-example .highlight-code")
|
||||
.contains(expectedValue)
|
||||
})
|
||||
it("should render a custom example when a schema is defined", () => {
|
||||
cy.visit("/?url=/documents/bugs/5458.yaml")
|
||||
.get("#operations-default-get_foo2")
|
||||
.click()
|
||||
.get(".model-example .highlight-code")
|
||||
.contains(expectedValue)
|
||||
})
|
||||
})
|
20
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5660.js
Normal file
20
frontend/web/api-doc/test/e2e-cypress/tests/bugs/5660.js
Normal file
@ -0,0 +1,20 @@
|
||||
// http://github.com/swagger-api/swagger-ui/issues/5660
|
||||
|
||||
const expectedValue = "nullable: true"
|
||||
|
||||
describe("#5660: Nullable object", () => {
|
||||
it("should render `nullable` marker for object itself", () => {
|
||||
cy.visit("/?url=/documents/bugs/5660-model.yaml")
|
||||
.get("#model-SomeObject .model-toggle")
|
||||
.click()
|
||||
.get("#model-SomeObject > .model-box")
|
||||
.contains(expectedValue)
|
||||
})
|
||||
it("should render `nullable` marker for next object in property", () => {
|
||||
cy.visit("/?url=/documents/bugs/5660-property.yaml")
|
||||
.get("#model-SomeObject .model-toggle")
|
||||
.click()
|
||||
.get("#model-SomeObject > .model-box")
|
||||
.contains(expectedValue)
|
||||
})
|
||||
})
|
42
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6016.js
Normal file
42
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6016.js
Normal file
@ -0,0 +1,42 @@
|
||||
describe("Entries should be valid property name", () => {
|
||||
it("should render a OAS3.0 definition that uses 'entries' as a 'components' property name", () => {
|
||||
cy.visit("/?url=/documents/bugs/6016-oas3.yaml")
|
||||
.get("#operations-tag-default")
|
||||
.should("exist")
|
||||
})
|
||||
it("should render expanded Operations of OAS3.0 definition that uses 'entries' as a 'components' property name", () => {
|
||||
cy.visit("/?url=/documents/bugs/6016-oas3.yaml")
|
||||
.get("#operations-default-test_test__get")
|
||||
.click()
|
||||
.get("#operations-default-test_test__get > div .opblock-body")
|
||||
.should("exist")
|
||||
|
||||
})
|
||||
it("should render expanded Models of OAS3.0 definition that uses 'entries' as a 'components' property name", () => {
|
||||
cy.visit("/?url=/documents/bugs/6016-oas3.yaml")
|
||||
.get("#model-Testmodel > span .model-box")
|
||||
.click()
|
||||
.get("div .model-box")
|
||||
.should("exist")
|
||||
})
|
||||
it("should render a OAS2.0 definition that uses 'entries' as a 'definitions' property name", () => {
|
||||
cy.visit("/?url=/documents/bugs/6016-oas2.yaml")
|
||||
.get("#operations-default-post_pet")
|
||||
.should("exist")
|
||||
})
|
||||
it("should render expanded Operations of OAS2.0 definition that uses 'entries' as a 'definitions' property name", () => {
|
||||
cy.visit("/?url=/documents/bugs/6016-oas2.yaml")
|
||||
.get("#operations-default-post_pet")
|
||||
.click()
|
||||
.get("#operations-default-post_pet > div .opblock-body")
|
||||
.should("exist")
|
||||
|
||||
})
|
||||
it("should render expanded Models of OAS2.0 definition that uses 'entries' as a 'defintions' property name", () => {
|
||||
cy.visit("/?url=/documents/bugs/6016-oas2.yaml")
|
||||
.get("#model-Pet > span .model-box")
|
||||
.click()
|
||||
.get("div .model-box")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
54
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6158.js
Normal file
54
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6158.js
Normal file
@ -0,0 +1,54 @@
|
||||
describe("#6158: read-only property is not hidden in `POST/PUT`", () => {
|
||||
describe("POST", () => {
|
||||
it("should hide property 'id'", () => {
|
||||
cy.visit("/?url=/documents/bugs/6158.yaml")
|
||||
.get("#operations-User-post_users")
|
||||
.click()
|
||||
.get(".parameters[data-property-name='id']")
|
||||
.should("not.exist")
|
||||
.get(".parameters[data-property-name='name']")
|
||||
.should("exist")
|
||||
})
|
||||
it("should hide property 'id' when trying it out", () => {
|
||||
cy.visit("/?url=/documents/bugs/6158.yaml")
|
||||
.get("#operations-User-post_users")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters[data-property-name='id']")
|
||||
.should("not.exist")
|
||||
.get("input[placeholder='id']")
|
||||
.should("not.exist")
|
||||
.get(".parameters[data-property-name='name']")
|
||||
.should("exist")
|
||||
.get("input[placeholder='name']")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
describe("PUT", () => {
|
||||
it("should hide property 'id'", () => {
|
||||
cy.visit("/?url=/documents/bugs/6158.yaml")
|
||||
.get("#operations-User-put_users")
|
||||
.click()
|
||||
.get(".parameters[data-property-name='id']")
|
||||
.should("not.exist")
|
||||
.get(".parameters[data-property-name='name']")
|
||||
.should("exist")
|
||||
})
|
||||
it("should hide property 'id' when trying it out", () => {
|
||||
cy.visit("/?url=/documents/bugs/6158.yaml")
|
||||
.get("#operations-User-put_users")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters[data-property-name='id']")
|
||||
.should("not.exist")
|
||||
.get("input[placeholder='id']")
|
||||
.should("not.exist")
|
||||
.get(".parameters[data-property-name='name']")
|
||||
.should("exist")
|
||||
.get("input[placeholder='name']")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
})
|
45
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6183.js
Normal file
45
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6183.js
Normal file
@ -0,0 +1,45 @@
|
||||
describe("When trying it out", () => {
|
||||
it("should render the response headers as comma separated lists", () => {
|
||||
cy.intercept(
|
||||
{
|
||||
method: "GET",
|
||||
url: /^\/response-headers/,
|
||||
hostname: "httpbin.org",
|
||||
},
|
||||
{
|
||||
body: {
|
||||
"Access-Control-Expose-Headers": "X-Header1, X-Header2, X-Header3, Access-Control-Expose-Headers",
|
||||
"Content-Length": "289",
|
||||
"Content-Type": "application/json",
|
||||
"X-Header1": "value1,value2",
|
||||
"X-Header2": "value3,value4",
|
||||
"X-Header3": ["value5", "value6"]
|
||||
},
|
||||
headers: {
|
||||
"access-control-expose-headers": "X-Header1,X-Header2,X-Header3,Access-Control-Expose-Headers",
|
||||
"content-type": "application/json",
|
||||
"x-header1": "value1,value2",
|
||||
"x-header2": "value3,value4",
|
||||
"x-header3": "value5,value6",
|
||||
}
|
||||
})
|
||||
|
||||
cy.visit("/?url=/documents/bugs/6183.yaml")
|
||||
.get("#operations-default-get_response_headers")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
.wait(1000)
|
||||
.get(".response-col_description .microlight")
|
||||
.find(("span:contains(\"value1,value2\")"))
|
||||
.should("exist")
|
||||
.get(".response-col_description .microlight")
|
||||
.find(("span:contains(\"value3,value4\")"))
|
||||
.should("exist")
|
||||
.get(".response-col_description .microlight")
|
||||
.find(("span:contains(\"value5,value6\")"))
|
||||
.should("exist")
|
||||
})
|
||||
})
|
43
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6276.js
Normal file
43
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6276.js
Normal file
@ -0,0 +1,43 @@
|
||||
describe("#6276: Query parameter filter=true is filtering by the value 'true'", () => {
|
||||
describe("With filter=true", () => {
|
||||
it("should display the filter bar", () => {
|
||||
cy.visit("/?url=/documents/petstore.swagger.yaml&filter=true")
|
||||
.get(".operation-filter-input")
|
||||
.should("exist")
|
||||
.should("be.empty")
|
||||
.get(".opblock-tag[data-tag='pet']")
|
||||
.should("exist")
|
||||
.get(".opblock-tag[data-tag='store']")
|
||||
.should("exist")
|
||||
.get(".opblock-tag[data-tag='user']")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
describe("With filter=false", () => {
|
||||
it("should not display the filter bar", () => {
|
||||
cy.visit("/?url=/documents/petstore.swagger.yaml&filter=false")
|
||||
.get(".operation-filter-input")
|
||||
.should("not.exist")
|
||||
.get(".opblock-tag[data-tag='pet']")
|
||||
.should("exist")
|
||||
.get(".opblock-tag[data-tag='store']")
|
||||
.should("exist")
|
||||
.get(".opblock-tag[data-tag='user']")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
describe("With filter=pet", () => {
|
||||
it("should display the filter bar and only show the operations tagged with pet", () => {
|
||||
cy.visit("/?url=/documents/petstore.swagger.yaml&filter=pet")
|
||||
.get(".operation-filter-input")
|
||||
.should("exist")
|
||||
.should("have.value", "pet")
|
||||
.get(".opblock-tag[data-tag='pet']")
|
||||
.should("exist")
|
||||
.get(".opblock-tag[data-tag='store']")
|
||||
.should("not.exist")
|
||||
.get(".opblock-tag[data-tag='user']")
|
||||
.should("not.exist")
|
||||
})
|
||||
})
|
||||
})
|
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6351.js
Normal file
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6351.js
Normal file
@ -0,0 +1,11 @@
|
||||
// http://github.com/swagger-api/swagger-ui/issues/6351
|
||||
|
||||
describe("#6351: Server dropdown should change when switched via oas3Actions.setSelectedServer", () => {
|
||||
it("should show different selected server", () => {
|
||||
cy.visit("/?url=/documents/bugs/6351.yaml")
|
||||
.get("select").should("have.value", "http://testserver1.com")
|
||||
.window()
|
||||
.then(win => win.ui.oas3Actions.setSelectedServer("http://testserver2.com"))
|
||||
.get("select").should("have.value", "http://testserver2.com")
|
||||
})
|
||||
})
|
44
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6369.js
Normal file
44
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6369.js
Normal file
@ -0,0 +1,44 @@
|
||||
describe("#6369: Object model render of field: deprecated", () => {
|
||||
describe("OAS3", () => {
|
||||
it("should display row with td:deprecated when set to true", () => {
|
||||
cy.visit("/?url=/documents/bugs/6369-oas3-display.yaml")
|
||||
.get("#model-IdentificationProfile > .model-box")
|
||||
.click()
|
||||
.get("#model-IdentificationProfile .model-box .model .inner-object table")
|
||||
.find("tr")
|
||||
.should("have.length", 3)
|
||||
.contains("td", "deprecated")
|
||||
})
|
||||
it("should not display row with td:deprecated when set to false", () => {
|
||||
cy.visit("/?url=/documents/bugs/6369-oas3-no-display.yaml")
|
||||
.get("#model-IdentificationProfile > .model-box")
|
||||
.click()
|
||||
.get("#model-IdentificationProfile .model-box .model .inner-object table")
|
||||
.find("tr")
|
||||
.should("have.length", 2)
|
||||
.get("#model-IdentificationProfile .model-box .model .inner-object table")
|
||||
.find(("td:contains(\"deprecated\")"))
|
||||
.should("not.exist")
|
||||
})
|
||||
})
|
||||
describe ("OAS2", () => {
|
||||
it("should display row with td:deprecated when set to true", () => {
|
||||
cy.visit("/?url=/documents/bugs/6369-oas2-display.yaml")
|
||||
.get("#model-IdentificationProfile > .model-box")
|
||||
.click()
|
||||
.get("#model-IdentificationProfile .model-box .model .inner-object")
|
||||
.contains("td", "deprecated")
|
||||
})
|
||||
it("should not display row with td:deprecated when set to false", () => {
|
||||
cy.visit("/?url=/documents/bugs/6369-oas2-no-display.yaml")
|
||||
.get("#model-IdentificationProfile > .model-box")
|
||||
.click()
|
||||
.get("#model-IdentificationProfile .model-box .model .inner-object table")
|
||||
.find("tr")
|
||||
.should("have.length", 2)
|
||||
.get("#model-IdentificationProfile .model-box .model .inner-object table")
|
||||
.find(("td:contains(\"deprecated\")"))
|
||||
.should("not.exist")
|
||||
})
|
||||
})
|
||||
})
|
33
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6442.js
Normal file
33
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6442.js
Normal file
@ -0,0 +1,33 @@
|
||||
describe("#6442: 'Examples' keyword definitions can not be rendered as xml", () => {
|
||||
it("should render response examples accourdingly to content-type xml", () => {
|
||||
const xmlIndicator = "<x>should be xml</x>"
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/6442.yaml")
|
||||
.get("#operations-default-xmlTest")
|
||||
.click()
|
||||
.get(".responses-wrapper")
|
||||
.within(() => {
|
||||
cy
|
||||
.get(".microlight")
|
||||
.should("include.text", xmlIndicator)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#6442: 'Example' keyword definitions can not be rendered as xml", () => {
|
||||
it("should render response examples accourdingly to content-type xml", () => {
|
||||
const xmlIndicator = "<x>should be xml</x>"
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/6442.yaml")
|
||||
.get("#operations-default-xmlTest2")
|
||||
.click()
|
||||
.get(".responses-wrapper")
|
||||
.within(() => {
|
||||
cy
|
||||
.get(".microlight")
|
||||
.should("include.text", xmlIndicator)
|
||||
})
|
||||
})
|
||||
})
|
65
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6475.js
Normal file
65
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6475.js
Normal file
@ -0,0 +1,65 @@
|
||||
describe("#6475: 'Examples' keyword definitions can not be rendered as xml", () => {
|
||||
it("should render requestBody examples preview accourdingly to content-type xml", () => {
|
||||
const xmlIndicator = "<x>should be xml</x>"
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/6475.yaml")
|
||||
.get("#operations-default-xmlTest_examples")
|
||||
.click()
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get(".microlight")
|
||||
.should("include.text", xmlIndicator)
|
||||
})
|
||||
})
|
||||
it("should requestBody examples input accourdingly to content-type xml", () => {
|
||||
const xmlIndicator = "<x>should be xml</x>"
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/6475.yaml")
|
||||
.get("#operations-default-xmlTest_examples")
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get("textarea")
|
||||
.contains(xmlIndicator)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#6475: 'Example' keyword definitions can not be rendered as xml", () => {
|
||||
it("should render requestBody examples preview accourdingly to content-type xml", () => {
|
||||
const xmlIndicator = "<x>should be xml</x>"
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/6475.yaml")
|
||||
.get("#operations-default-xmlTest_example")
|
||||
.click()
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get(".microlight")
|
||||
.should("include.text", xmlIndicator)
|
||||
})
|
||||
})
|
||||
it("should requestBody examples input accourdingly to content-type xml", () => {
|
||||
const xmlIndicator = "<x>should be xml</x>"
|
||||
|
||||
cy
|
||||
.visit("?url=/documents/bugs/6475.yaml")
|
||||
.get("#operations-default-xmlTest_example")
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get("textarea")
|
||||
.contains(xmlIndicator)
|
||||
})
|
||||
})
|
||||
})
|
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6540.js
Normal file
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6540.js
Normal file
@ -0,0 +1,11 @@
|
||||
describe("#6540: XML example not rendered correctly with oneOf", () => {
|
||||
it("should render xml like json", () => {
|
||||
const expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n\t<a>string</a>\n\t<b>0</b>\n\t<c>\n\t\t<ObjectType>Text</ObjectType>\n\t\t<Data>This is a text</Data>\n\t</c>\n\t<c>\n\t\t<ObjectType>image</ObjectType>\n\t\t<Data>This is a image</Data>\n\t</c>\n\t<d>\n\t\t<ObjectType>Text</ObjectType>\n\t\t<Data>This is a text</Data>\n\t</d>\n\t<d>\n\t\t<ObjectType>image</ObjectType>\n\t\t<Data>This is a image</Data>\n\t</d>\n</test>"
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/6540.yaml")
|
||||
.get("#operations-Test-postTest")
|
||||
.click()
|
||||
.get(".microlight")
|
||||
.contains(expected)
|
||||
})
|
||||
})
|
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6627.js
Normal file
11
frontend/web/api-doc/test/e2e-cypress/tests/bugs/6627.js
Normal file
@ -0,0 +1,11 @@
|
||||
describe("#6627: XML example when defined as array", () => {
|
||||
it("should render xml like json", () => {
|
||||
const expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Users>\n\t<User id=\"123\" name=\"bob\">\n\t</User>\n\t<User id=\"456\" name=\"jane\">\n\t</User>\n</Users>"
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/6627.yaml")
|
||||
.get("#operations-default-get_users")
|
||||
.click()
|
||||
.get(".microlight")
|
||||
.contains(expected)
|
||||
})
|
||||
})
|
14
frontend/web/api-doc/test/e2e-cypress/tests/bugs/7996.js
Normal file
14
frontend/web/api-doc/test/e2e-cypress/tests/bugs/7996.js
Normal file
@ -0,0 +1,14 @@
|
||||
describe("#7996: tag description text fills container when externalDocs section absent", () => {
|
||||
it("should show externalDocs div when externalDocs present in specification", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/7996-tags-externalDocs.yaml")
|
||||
.get("#operations-tag-foo .info__externaldocs")
|
||||
.should("exist")
|
||||
})
|
||||
it("should have no externalDocs div when externalDocs absent from specification", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/7996-tags-externalDocs.yaml")
|
||||
.get("#operations-tag-bar .info__externaldocs")
|
||||
.should("not.exist")
|
||||
})
|
||||
})
|
24
frontend/web/api-doc/test/e2e-cypress/tests/bugs/8217.js
Normal file
24
frontend/web/api-doc/test/e2e-cypress/tests/bugs/8217.js
Normal file
@ -0,0 +1,24 @@
|
||||
describe("#8217: Reset Request Body not using default values", () => {
|
||||
it("it reset the user edited value and executes with the default value in case of try out reset. (#6517)", () => {
|
||||
cy
|
||||
.visit("?url=/documents/bugs/8217.yaml")
|
||||
.get("#operations-default-addPet")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// replace default sample with bad value
|
||||
.get(`.parameters[data-property-name="bodyParameter"] input`)
|
||||
.type("{selectall}not the default value")
|
||||
// Reset Try It Out
|
||||
.get(".try-out__btn.reset")
|
||||
.click()
|
||||
// Submit using default value
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
// No required validation error on body parameter
|
||||
.get(`.parameters[data-property-name="bodyParameter"] input`)
|
||||
.should("have.value", "default")
|
||||
.and("not.have.class", "invalid")
|
||||
})
|
||||
})
|
@ -0,0 +1,26 @@
|
||||
import repeat from "lodash/repeat"
|
||||
|
||||
describe("Editor #1868: model changes break rendering", () => {
|
||||
it("should render model content changes correctly", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/bugs/editor-1868.yaml")
|
||||
|
||||
.get(".model-toggle.collapsed")
|
||||
.click()
|
||||
|
||||
.get("#model-MyModel")
|
||||
.contains("a")
|
||||
|
||||
.window()
|
||||
.then(win => {
|
||||
// Simulate Swagger Editor updating a model
|
||||
const content = win.ui.specSelectors.specStr()
|
||||
win.ui.specActions.updateSpec(content + `\n b:\n type: string`)
|
||||
})
|
||||
|
||||
.get("#model-MyModel")
|
||||
.contains("a")
|
||||
.get("#model-MyModel")
|
||||
.contains("b")
|
||||
})
|
||||
})
|
35
frontend/web/api-doc/test/e2e-cypress/tests/bugs/swos-63.js
Normal file
35
frontend/web/api-doc/test/e2e-cypress/tests/bugs/swos-63.js
Normal file
@ -0,0 +1,35 @@
|
||||
describe("SWOS-63: Schema/Model labeling", () => {
|
||||
describe("SchemaS/Models section", () => {
|
||||
it("should render `Schemas` for OpenAPI 3", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.get("section.models > h4")
|
||||
.contains("Schemas")
|
||||
})
|
||||
it("should render `Models` for OpenAPI 2", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore.swagger.yaml")
|
||||
.get("section.models > h4")
|
||||
.contains("Models")
|
||||
})
|
||||
})
|
||||
describe("ModelExample within Operation", () => {
|
||||
it("should render `Schemas` for OpenAPI 3", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.get("#operations-default-findPets")
|
||||
.click()
|
||||
.get("button.tablinks[data-name=model]")
|
||||
.contains("Schema")
|
||||
})
|
||||
it("should render `Models` for OpenAPI 2", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/petstore.swagger.yaml")
|
||||
.get("section.models > h4")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get("button.tablinks[data-name=model]")
|
||||
.contains("Model")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,51 @@
|
||||
describe("OAuth2 Bearer flow", () => {
|
||||
beforeEach(() => {
|
||||
const staticResponse = {
|
||||
statusCode: 200,
|
||||
body: {
|
||||
name: "not a random secret for test",
|
||||
}
|
||||
}
|
||||
cy.intercept("GET", "/get*", staticResponse).as(
|
||||
"tokenRequest"
|
||||
)
|
||||
})
|
||||
|
||||
it("should be focused on input field with aria-label", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/auth-bearer-flow.yaml"
|
||||
)
|
||||
.get("button.authorize")
|
||||
.click()
|
||||
cy.focused()
|
||||
.should("have.attr", "aria-label").and("eq", "auth-bearer-value")
|
||||
})
|
||||
it("should make a header request with proper sample cURL header", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/auth-bearer-flow.yaml"
|
||||
)
|
||||
.get("button.authorize")
|
||||
.click()
|
||||
.get("section > input")
|
||||
.type("secret_token")
|
||||
.get(".auth-btn-wrapper > .authorize")
|
||||
.click()
|
||||
.get("button.close-modal")
|
||||
.click()
|
||||
// Try-it-out
|
||||
.get("#operations-default-get_get")
|
||||
.click()
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
cy.wait("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.its("authorization")
|
||||
.should("equal", "Bearer secret_token")
|
||||
.get(".curl")
|
||||
.contains("Authorization: Bearer secret_token")
|
||||
.should("be.visible")
|
||||
})
|
||||
})
|
@ -0,0 +1,47 @@
|
||||
describe("Check client_secret for OAuth2 Authorization Code flow with and without PKCE (#6290)", () => {
|
||||
it("should display client_secret field for authorization code flow with PKCE", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/auth-code-flow-pkce-without-secret.yaml"
|
||||
)
|
||||
.window()
|
||||
.then(win => {
|
||||
// set auth config to use PKCE
|
||||
let authConfigs = win.ui.authSelectors.getConfigs()
|
||||
win.ui.authActions.configureAuth({
|
||||
...authConfigs,
|
||||
usePkceWithAuthorizationCodeGrant: true,
|
||||
})
|
||||
})
|
||||
.get("button.authorize")
|
||||
.click()
|
||||
.get("h4")
|
||||
.contains("authorizationCode with PKCE")
|
||||
.get(".flow")
|
||||
.contains("authorizationCode with PKCE")
|
||||
.get("#client_secret")
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it("should display client_secret field for authorization code flow without PKCE", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/auth-code-flow-pkce-without-secret.yaml"
|
||||
)
|
||||
.window()
|
||||
.then(win => {
|
||||
// set auth config to not use PKCE
|
||||
let authConfigs = win.ui.authSelectors.getConfigs()
|
||||
win.ui.authActions.configureAuth({
|
||||
...authConfigs,
|
||||
usePkceWithAuthorizationCodeGrant: false,
|
||||
})
|
||||
})
|
||||
.get("button.authorize")
|
||||
.click()
|
||||
.get("h4")
|
||||
.contains("authorizationCode")
|
||||
.get(".flow")
|
||||
.contains("authorizationCode")
|
||||
.get("#client_secret")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
@ -0,0 +1,292 @@
|
||||
describe("Deep linking feature", () => {
|
||||
describe("in Swagger 2", () => {
|
||||
const swagger2BaseUrl = "/?deepLinking=true&url=/documents/features/deep-linking.swagger.yaml"
|
||||
|
||||
describe("regular Operation", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet: ".opblock-get",
|
||||
correctElementId: "operations-myTag-myOperation",
|
||||
correctFragment: "#/myTag/myOperation",
|
||||
correctHref: "#/myTag/myOperation"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with whitespace in tag+id", () => {
|
||||
const elementToGet = ".opblock-post"
|
||||
const correctFragment = "#/my%20Tag/my%20Operation"
|
||||
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet,
|
||||
correctElementId: "operations-my_Tag-my_Operation",
|
||||
correctFragment,
|
||||
correctHref: "#/my%20Tag/my%20Operation"
|
||||
})
|
||||
|
||||
const legacyFragment = "#/my_Tag/my_Operation"
|
||||
|
||||
it("should expand the operation when reloaded and provided the legacy fragment", () => {
|
||||
cy.visit(`${swagger2BaseUrl}${legacyFragment}`)
|
||||
.reload()
|
||||
.get(`${elementToGet}.is-open`)
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it.skip("should rewrite to the correct fragment when provided the legacy fragment", () => {
|
||||
cy.visit(`${swagger2BaseUrl}${legacyFragment}`)
|
||||
.reload()
|
||||
.window()
|
||||
.should("have.deep.property", "location.hash", correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with underscores in tag+id", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet: ".opblock-patch",
|
||||
correctElementId: "operations-underscore_Tag-underscore_Operation",
|
||||
correctFragment: "#/underscore_Tag/underscore_Operation",
|
||||
correctHref: "#/underscore_Tag/underscore_Operation"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with UTF-16 characters", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet: ".opblock-head",
|
||||
correctElementId: "operations-шеллы-пошел",
|
||||
correctFragment: "#/%D1%88%D0%B5%D0%BB%D0%BB%D1%8B/%D0%BF%D0%BE%D1%88%D0%B5%D0%BB",
|
||||
correctHref: "#/шеллы/пошел"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with no operationId", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet: ".opblock-put",
|
||||
correctElementId: "operations-tagTwo-put_noOperationId",
|
||||
correctFragment: "#/tagTwo/put_noOperationId",
|
||||
correctHref: "#/tagTwo/put_noOperationId"
|
||||
})
|
||||
})
|
||||
|
||||
describe("regular Tag", () => {
|
||||
TagDeeplinkTestFactory({
|
||||
isTagCase: true,
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet: `.opblock-tag[data-tag="myTag"][data-is-open="true"]`,
|
||||
correctElementId: "operations-tag-myTag",
|
||||
correctFragment: "#/myTag",
|
||||
correctHref: "#/myTag"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Tag with whitespace", () => {
|
||||
TagDeeplinkTestFactory({
|
||||
isTagCase: true,
|
||||
baseUrl: swagger2BaseUrl,
|
||||
elementToGet: `.opblock-tag[data-tag="my Tag"][data-is-open="true"]`,
|
||||
correctElementId: "operations-tag-my_Tag",
|
||||
correctFragment: "#/my%20Tag",
|
||||
correctHref: "#/my%20Tag"
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("in OpenAPI 3", () => {
|
||||
const openAPI3BaseUrl = "/?deepLinking=true&url=/documents/features/deep-linking.openapi.yaml"
|
||||
|
||||
describe("regular Operation", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: ".opblock-get",
|
||||
correctElementId: "operations-myTag-myOperation",
|
||||
correctFragment: "#/myTag/myOperation",
|
||||
correctHref: "#/myTag/myOperation"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with whitespace in tag+id", () => {
|
||||
const elementToGet = ".opblock-post"
|
||||
const correctFragment = "#/my%20Tag/my%20Operation"
|
||||
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: ".opblock-post",
|
||||
correctElementId: "operations-my_Tag-my_Operation",
|
||||
correctFragment,
|
||||
correctHref: "#/my%20Tag/my%20Operation"
|
||||
})
|
||||
|
||||
const legacyFragment = "#/my_Tag/my_Operation"
|
||||
|
||||
it("should expand the operation when reloaded and provided the legacy fragment", () => {
|
||||
cy.visit(`${openAPI3BaseUrl}${legacyFragment}`)
|
||||
.reload()
|
||||
.get(`${elementToGet}.is-open`)
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
|
||||
it.skip("should rewrite to the correct fragment when provided the legacy fragment", () => {
|
||||
cy.visit(`${openAPI3BaseUrl}${legacyFragment}`)
|
||||
.reload()
|
||||
.window()
|
||||
.should("have.deep.property", "location.hash", correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with underscores in tag+id", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: ".opblock-patch",
|
||||
correctElementId: "operations-underscore_Tag-underscore_Operation",
|
||||
correctFragment: "#/underscore_Tag/underscore_Operation",
|
||||
correctHref: "#/underscore_Tag/underscore_Operation"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with UTF-16 characters", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: ".opblock-head",
|
||||
correctElementId: "operations-шеллы-пошел",
|
||||
correctFragment: "#/%D1%88%D0%B5%D0%BB%D0%BB%D1%8B/%D0%BF%D0%BE%D1%88%D0%B5%D0%BB",
|
||||
correctHref: "#/шеллы/пошел"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Operation with no operationId", () => {
|
||||
OperationDeeplinkTestFactory({
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: ".opblock-put",
|
||||
correctElementId: "operations-tagTwo-put_noOperationId",
|
||||
correctFragment: "#/tagTwo/put_noOperationId",
|
||||
correctHref: "#/tagTwo/put_noOperationId"
|
||||
})
|
||||
})
|
||||
|
||||
describe("regular Tag", () => {
|
||||
TagDeeplinkTestFactory({
|
||||
isTagCase: true,
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: `.opblock-tag[data-tag="myTag"][data-is-open="true"]`,
|
||||
correctElementId: "operations-tag-myTag",
|
||||
correctFragment: "#/myTag",
|
||||
correctHref: "#/myTag"
|
||||
})
|
||||
})
|
||||
|
||||
describe("Tag with whitespace", () => {
|
||||
TagDeeplinkTestFactory({
|
||||
isTagCase: true,
|
||||
baseUrl: openAPI3BaseUrl,
|
||||
elementToGet: `.opblock-tag[data-tag="my Tag"][data-is-open="true"]`,
|
||||
correctElementId: "operations-tag-my_Tag",
|
||||
correctFragment: "#/my%20Tag",
|
||||
correctHref: "#/my%20Tag"
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function OperationDeeplinkTestFactory({ baseUrl, elementToGet, correctElementId, correctFragment, correctHref }) {
|
||||
it("should generate a correct element ID", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(elementToGet)
|
||||
.should("have.id", correctElementId)
|
||||
})
|
||||
|
||||
it("should add the correct element fragment to the URL when expanded", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(elementToGet)
|
||||
.click()
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.hash).to.eq(correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
it("should provide an anchor link that has the correct fragment as href", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(elementToGet)
|
||||
.find("a")
|
||||
.should("have.attr", "href", correctHref)
|
||||
.click()
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.hash).to.eq(correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
it("should expand the operation when reloaded", () => {
|
||||
cy.visit(`${baseUrl}${correctFragment}`)
|
||||
.get(`${elementToGet}.is-open`)
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it("should retain the correct fragment when reloaded", () => {
|
||||
cy.visit(`${baseUrl}${correctFragment}`)
|
||||
.reload()
|
||||
.should("exist")
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.hash).to.eq(correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
it("should expand a tag with docExpansion disabled", () => {
|
||||
cy.visit(`${baseUrl}&docExpansion=none${correctFragment}`)
|
||||
.get(`.opblock-tag-section.is-open`)
|
||||
.should("have.length", 1)
|
||||
})
|
||||
|
||||
it("should expand an operation with docExpansion disabled", () => {
|
||||
cy.visit(`${baseUrl}&docExpansion=none${correctFragment}`)
|
||||
.get(`.opblock.is-open`)
|
||||
.should("have.length", 1)
|
||||
})
|
||||
}
|
||||
|
||||
function TagDeeplinkTestFactory({ baseUrl, elementToGet, correctElementId, correctFragment, correctHref, isTagCase = false }) {
|
||||
it("should generate a correct element ID", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(elementToGet)
|
||||
.should("have.id", correctElementId)
|
||||
})
|
||||
|
||||
it("should add the correct element fragment to the URL when expanded", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(elementToGet)
|
||||
.click()
|
||||
.click() // tags need two clicks because they're expanded by default
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.hash).to.eq(correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
it("should provide an anchor link that has the correct fragment as href", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(elementToGet)
|
||||
.find("a")
|
||||
.should("have.attr", "href", correctHref)
|
||||
})
|
||||
|
||||
it("should expand the tag when reloaded", () => {
|
||||
cy.visit(`${baseUrl}${correctFragment}`)
|
||||
.get(`${elementToGet}[data-is-open="true"]`)
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it("should retain the correct fragment when reloaded", () => {
|
||||
cy.visit(`${baseUrl}${correctFragment}`)
|
||||
.reload()
|
||||
.should("exist")
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.hash).to.eq(correctFragment)
|
||||
})
|
||||
})
|
||||
|
||||
it("should expand a tag with docExpansion disabled", () => {
|
||||
cy.visit(`${baseUrl}&docExpansion=none${correctFragment}`)
|
||||
.get(`.opblock-tag-section.is-open`)
|
||||
.should("have.length", 1)
|
||||
})
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
describe("dynamic default oauth2RedirectUrl", () => {
|
||||
it("should compute an oauth2RedirectUrl based on the browser's location at runtime", () => {
|
||||
cy.visit("/")
|
||||
.window()
|
||||
.then(win => win.ui.getConfigs())
|
||||
.should("include", { oauth2RedirectUrl: "http://localhost:3230/oauth2-redirect.html" })
|
||||
})
|
||||
it("should compute an oauth2RedirectUrl based on the browser's location at runtime, including the path", () => {
|
||||
cy.visit("/pages/5085/")
|
||||
.window()
|
||||
.then(win => win.ui.getConfigs())
|
||||
.should("include", { oauth2RedirectUrl: "http://localhost:3230/pages/5085/oauth2-redirect.html" })
|
||||
})
|
||||
it("should compute an oauth2RedirectUrl based on the browser's location at runtime, including the path, without confusing the file name for a folder name", () => {
|
||||
cy.visit("/pages/5085/index.html")
|
||||
.window()
|
||||
.then(win => win.ui.getConfigs())
|
||||
.should("include", { oauth2RedirectUrl: "http://localhost:3230/pages/5085/oauth2-redirect.html" })
|
||||
})
|
||||
it("should compute an oauth2RedirectUrl based on the browser's location at runtime, including the path, even it does not end with a slash", () => {
|
||||
cy.visit("/pages/5085")
|
||||
.window()
|
||||
.then(win => win.ui.getConfigs())
|
||||
.should("include", { oauth2RedirectUrl: "http://localhost:3230/pages/5085/oauth2-redirect.html" })
|
||||
})
|
||||
})
|
@ -0,0 +1,108 @@
|
||||
describe("External docs feature", () => {
|
||||
describe("in Swagger 2", () => {
|
||||
ExternalDocsTest("/?url=/documents/features/external-docs.swagger.yaml")
|
||||
})
|
||||
describe("in OpenAPI 3", () => {
|
||||
ExternalDocsTest("/?url=/documents/features/external-docs.openapi.yaml")
|
||||
})
|
||||
})
|
||||
|
||||
function ExternalDocsTest(baseUrl) {
|
||||
describe("for Root", () => {
|
||||
it("should display link to external docs with description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(".info__extdocs")
|
||||
.should("exist")
|
||||
.and("contain.text", "Read external docs")
|
||||
.and("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
|
||||
it("should display link to external docs without description", () => {
|
||||
cy
|
||||
.intercept({
|
||||
path: /^\/documents\/features\/external-docs\.(swagger|openapi)\.yaml\?intercept$/
|
||||
}, (req) => {
|
||||
delete req.headers["if-none-match"]
|
||||
delete req.headers["if-modified-since"]
|
||||
req.continue((res) => {
|
||||
res.send({body: res.body.replace(" description: Read external docs\n", "")})
|
||||
})
|
||||
})
|
||||
.visit(`${baseUrl}?intercept`)
|
||||
.get(".info__extdocs")
|
||||
.should("exist")
|
||||
.and("contain.text", "http://swagger.io")
|
||||
.and("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
})
|
||||
|
||||
describe("for Tags", () => {
|
||||
it("should display link to external docs with description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(`.opblock-tag[data-tag="pet"] .info__externaldocs`)
|
||||
.should("exist")
|
||||
.find("a")
|
||||
.should("contain.text", "Pet Documentation")
|
||||
.and("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
|
||||
it("should display link to external docs without description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(`.opblock-tag[data-tag="petWithoutDescription"] .info__externaldocs`)
|
||||
.should("exist")
|
||||
.find("a")
|
||||
.should("contain.text", "http://swagger.io")
|
||||
.and("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
})
|
||||
|
||||
describe("for Schemas", () => {
|
||||
function SchemaTestFactory(type) {
|
||||
return () => {
|
||||
it("should display link with description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(`.models #model-${type} button`)
|
||||
.click()
|
||||
.get(`.models #model-${type} .external-docs a`)
|
||||
.should("contain.text", `${type} Docs`)
|
||||
.and("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
|
||||
it("should display link without description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(`.models #model-${type}WithoutDescription button`)
|
||||
.click()
|
||||
.get(`.models #model-${type}WithoutDescription .external-docs a`)
|
||||
.should("contain.text", "http://swagger.io")
|
||||
.and("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
describe("Primitive Schema", SchemaTestFactory("Primitive"))
|
||||
describe("Array Schema", SchemaTestFactory("Array"))
|
||||
describe("Object Schema", SchemaTestFactory("Object"))
|
||||
})
|
||||
|
||||
describe("for Operation", () => {
|
||||
it("should display link to external docs with description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get("#operations-pet-updatePet button")
|
||||
.click()
|
||||
.get("#operations-pet-updatePet .opblock-external-docs-wrapper .opblock-external-docs__description")
|
||||
.should("contain.text", "More details about putting a pet")
|
||||
.get("#operations-pet-updatePet .opblock-external-docs-wrapper .opblock-external-docs__link")
|
||||
.should("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
|
||||
it("should display link to external docs without description", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get("#operations-pet-addPet button")
|
||||
.click()
|
||||
.get("#operations-pet-addPet .opblock-external-docs-wrapper .opblock-external-docs__description")
|
||||
.should("not.exist")
|
||||
.get("#operations-pet-addPet .opblock-external-docs-wrapper .opblock-external-docs__link")
|
||||
.should("have.attr", "href", "http://swagger.io")
|
||||
})
|
||||
})
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
describe("Model collapse/expand feature", () => {
|
||||
describe("in Swagger 2", () => {
|
||||
const swagger2BaseUrl = "/?deepLinking=true&url=/documents/features/models.swagger.yaml"
|
||||
const urlFragment = "#/definitions/Pet"
|
||||
ModelCollapseTest(swagger2BaseUrl, urlFragment)
|
||||
})
|
||||
describe("in OpenAPI 3", () => {
|
||||
const openAPI3BaseUrl = "/?deepLinking=true&url=/documents/features/models.openapi.yaml"
|
||||
ModelCollapseTest(openAPI3BaseUrl)
|
||||
})
|
||||
})
|
||||
|
||||
function ModelCollapseTest(baseUrl, urlFragment) {
|
||||
it("Models section should be expanded on load", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(".models")
|
||||
.should("have.class", "is-open")
|
||||
.get("#model-Pet")
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it("Models section should collapse and expand when toggled", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get(".models h4 .models-control")
|
||||
.click()
|
||||
.get(".models")
|
||||
.should("not.have.class", "is-open")
|
||||
.get("#model-Order")
|
||||
.should("not.exist")
|
||||
.get(".models h4 .models-control")
|
||||
.click()
|
||||
.get(".models")
|
||||
.should("have.class", "is-open")
|
||||
.get("#model-Order")
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it("Model should collapse and expand when toggled clicking button", () => {
|
||||
cy.visit(baseUrl)
|
||||
.get("#model-User .model-box .model-box-control")
|
||||
.click()
|
||||
.get("#model-User .model-box .model .inner-object")
|
||||
.should("exist")
|
||||
.get("#model-User .model-box .model-box-control")
|
||||
.first()
|
||||
.click()
|
||||
.get("#model-User .model-box .model .inner-object")
|
||||
.should("not.exist")
|
||||
})
|
||||
}
|
@ -0,0 +1,662 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
const {
|
||||
ParameterPrimitiveTestCases,
|
||||
RequestBodyPrimitiveTestCases,
|
||||
ResponsePrimitiveTestCases,
|
||||
} = require("../../helpers/multiple-examples")
|
||||
describe("OpenAPI 3.0 Multiple Examples - core features", () => {
|
||||
describe("/String", () => {
|
||||
describe("in a parameter", () => {
|
||||
ParameterPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_String",
|
||||
parameterName: "message",
|
||||
exampleA: {
|
||||
key: "StringExampleA",
|
||||
value: "hello world",
|
||||
},
|
||||
exampleB: {
|
||||
key: "StringExampleB",
|
||||
value: "The quick brown fox jumps over the lazy dog",
|
||||
},
|
||||
customUserInput: "OpenAPIs.org <3",
|
||||
})
|
||||
})
|
||||
describe("in a Request Body", () => {
|
||||
RequestBodyPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_String",
|
||||
exampleA: {
|
||||
key: "StringExampleA",
|
||||
value: "hello world",
|
||||
serializedValue: "hello world",
|
||||
summary: "Don't just string me along...",
|
||||
},
|
||||
exampleB: {
|
||||
key: "StringExampleB",
|
||||
value: "The quick brown fox jumps over the lazy dog",
|
||||
serializedValue: "The quick brown fox jumps over the lazy dog",
|
||||
summary: "I'm a pangram!",
|
||||
},
|
||||
customUserInput: "OpenAPIs.org <3",
|
||||
})
|
||||
})
|
||||
describe("in a Response", () => {
|
||||
ResponsePrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_String",
|
||||
exampleA: {
|
||||
key: "StringExampleA",
|
||||
value: "hello world",
|
||||
summary: "Don't just string me along...",
|
||||
},
|
||||
exampleB: {
|
||||
key: "StringExampleB",
|
||||
value: "The quick brown fox jumps over the lazy dog",
|
||||
summary: "I'm a pangram!",
|
||||
},
|
||||
exampleC: {
|
||||
key: "StringExampleC",
|
||||
value: "JavaScript rules",
|
||||
summary: "A third example, for use in special places...",
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("/Number", () => {
|
||||
describe("in a parameter", () => {
|
||||
ParameterPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Number",
|
||||
parameterName: "message",
|
||||
exampleA: {
|
||||
key: "NumberExampleA",
|
||||
value: "7710263025",
|
||||
},
|
||||
exampleB: {
|
||||
key: "NumberExampleB",
|
||||
value: "9007199254740991",
|
||||
},
|
||||
exampleC: {
|
||||
key: "NumberExampleC",
|
||||
value: "0",
|
||||
},
|
||||
customUserInput: "9001",
|
||||
})
|
||||
})
|
||||
describe("in a Request Body", () => {
|
||||
RequestBodyPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Number",
|
||||
exampleA: {
|
||||
key: "NumberExampleA",
|
||||
value: "7710263025",
|
||||
summary: "World population",
|
||||
},
|
||||
exampleB: {
|
||||
key: "NumberExampleB",
|
||||
value: "9007199254740991",
|
||||
summary: "Number.MAX_SAFE_INTEGER",
|
||||
},
|
||||
exampleC: {
|
||||
key: "NumberExampleC",
|
||||
value: "0",
|
||||
},
|
||||
customUserInput: "1337",
|
||||
})
|
||||
})
|
||||
describe("in a Response", () => {
|
||||
ResponsePrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Number",
|
||||
exampleA: {
|
||||
key: "NumberExampleA",
|
||||
value: "7710263025",
|
||||
summary: "World population",
|
||||
},
|
||||
exampleB: {
|
||||
key: "NumberExampleB",
|
||||
value: "9007199254740991",
|
||||
summary: "Number.MAX_SAFE_INTEGER",
|
||||
},
|
||||
exampleC: {
|
||||
key: "NumberExampleC",
|
||||
value: "0",
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("/Boolean", () => {
|
||||
describe("in a parameter", () => {
|
||||
it("should render and apply the first example and value by default", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Boolean")
|
||||
.click()
|
||||
// Assert on the initial dropdown value
|
||||
.get("table.parameters .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "The truth will set you free")
|
||||
// Assert on the initial JsonSchemaForm value
|
||||
.get(".parameters-col_description > select")
|
||||
.should("have.attr", "disabled")
|
||||
.get(".parameters-col_description > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "true")
|
||||
// Execute
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".execute")
|
||||
.click()
|
||||
// Assert on the request URL
|
||||
.get(".request-url")
|
||||
.contains(`?message=true`)
|
||||
})
|
||||
it("should render and apply the second value when chosen", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Boolean")
|
||||
.click()
|
||||
// Set the dropdown value, then assert on it
|
||||
.get("table.parameters .examples-select > select")
|
||||
.select("BooleanExampleB")
|
||||
.find(":selected")
|
||||
.should("have.text", "Friends don't lie to friends")
|
||||
// Set the JsonSchemaForm value, then assert on it
|
||||
.get(".parameters-col_description > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "false")
|
||||
// Execute
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".execute")
|
||||
.click()
|
||||
// Assert on the request URL
|
||||
.get(".request-url")
|
||||
.contains(`?message=false`)
|
||||
})
|
||||
it("should track value changes against valid examples", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Boolean")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Set the JsonSchemaForm value, then assert on it
|
||||
.get(".parameters-col_description > select")
|
||||
.select("false")
|
||||
.find(":selected")
|
||||
.should("have.text", "false")
|
||||
// Assert on the dropdown value
|
||||
.get("table.parameters .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "Friends don't lie to friends")
|
||||
// Execute
|
||||
.get(".execute")
|
||||
.click()
|
||||
// Assert on the request URL
|
||||
.get(".request-url")
|
||||
.contains(`?message=false`)
|
||||
})
|
||||
})
|
||||
describe("in a Request Body", () => {
|
||||
RequestBodyPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Boolean",
|
||||
exampleA: {
|
||||
key: "BooleanExampleA",
|
||||
value: "true",
|
||||
summary: "The truth will set you free",
|
||||
},
|
||||
exampleB: {
|
||||
key: "BooleanExampleB",
|
||||
value: "false",
|
||||
summary: "Friends don't lie to friends",
|
||||
},
|
||||
customUserInput: "tralse",
|
||||
})
|
||||
})
|
||||
describe("in a Response", () => {
|
||||
it("should render and apply the first example and value by default", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Boolean")
|
||||
.click()
|
||||
// Assert on the initial dropdown value
|
||||
.get(".responses-wrapper .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "The truth will set you free")
|
||||
// Assert on the example value
|
||||
.get(".example.microlight")
|
||||
.should("have.text", "true")
|
||||
})
|
||||
it("should render and apply the second value when chosen", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Boolean")
|
||||
.click()
|
||||
// Set the dropdown value, then assert on it
|
||||
.get(".responses-wrapper .examples-select > select")
|
||||
.select("BooleanExampleB")
|
||||
.find(":selected")
|
||||
.should("have.text", "Friends don't lie to friends")
|
||||
// Assert on the example value
|
||||
.get(".example.microlight")
|
||||
.should("have.text", "false")
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("/Array", () => {
|
||||
describe("in a Parameter", () => {
|
||||
it("should have the first example's array entries by default", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of strings")
|
||||
})
|
||||
it("should switch to the second array's entries via dropdown", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of numbers")
|
||||
})
|
||||
it("should not allow modification of values in static mode", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item > input")
|
||||
.should("have.attr", "disabled")
|
||||
})
|
||||
it("should allow modification of values in Try-It-Out", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}5")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
})
|
||||
|
||||
it("should retain a modified value, and support returning to it", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}5")
|
||||
// Reset to an example
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of numbers")
|
||||
// Return to the modified value
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("__MODIFIED__VALUE__")
|
||||
// Assert that our modified value is back
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
})
|
||||
})
|
||||
describe("in a Request Body", () => {
|
||||
it("should have the first example's array entries by default", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Check HighlightCode value
|
||||
.get(".opblock-section-request-body .highlight-code")
|
||||
.should("include.text", JSON.stringify(["a", "b", "c"], null, 2))
|
||||
// Check dropdown value
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of strings")
|
||||
// Switch to Try-It-Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Check textarea value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.should("have.value", JSON.stringify(["a", "b", "c"], null, 2))
|
||||
// Check dropdown value
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of strings")
|
||||
})
|
||||
it("should switch to the second array's entries via dropdown", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
.get(".opblock-section-request-body .highlight-code")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4], null, 2))
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of numbers")
|
||||
// Switch to Try-It-Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Check textarea value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4], null, 2))
|
||||
// Check dropdown value
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of numbers")
|
||||
})
|
||||
it("should allow modification of values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Switch to Try-It-Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Choose the second example
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Change the value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.type(`{leftarrow}{leftarrow},{enter} 5`)
|
||||
// Check that [Modified value] is displayed in dropdown
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
// Check textarea value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4, 5], null, 2))
|
||||
})
|
||||
|
||||
it("should retain a modified value, and support returning to it", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Switch to Try-It-Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Choose the second example as the example to start with
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Change the value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.type(`{leftarrow}{leftarrow},{enter} 5`)
|
||||
// Check that [Modified value] is displayed in dropdown
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
// Check textarea value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4, 5], null, 2))
|
||||
// Choose the second example
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Check that the example is displayed in dropdown
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of numbers")
|
||||
// Check textarea value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4], null, 2))
|
||||
// Switch back to the modified value
|
||||
.get(".opblock-section-request-body .examples-select > select")
|
||||
.select("__MODIFIED__VALUE__")
|
||||
// Check textarea value
|
||||
.get(".opblock-section-request-body textarea")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4, 5], null, 2))
|
||||
})
|
||||
})
|
||||
describe("in a Response", () => {
|
||||
it("should render and apply the first example and value by default", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Assert on the initial dropdown value
|
||||
.get(".responses-wrapper .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of strings")
|
||||
// Assert on the example value
|
||||
.get(".example.microlight")
|
||||
.should("include.text", JSON.stringify(["a", "b", "c"], null, 2))
|
||||
})
|
||||
it("should render and apply the second value when chosen", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Set the dropdown value, then assert on it
|
||||
.get(".responses-wrapper .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
.find(":selected")
|
||||
.should("have.text", "A lowly array of numbers")
|
||||
// Assert on the example value
|
||||
.get(".example.microlight")
|
||||
.should("include.text", JSON.stringify([1, 2, 3, 4], null, 2))
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("/Object", () => {
|
||||
describe("in a Parameter", () => {
|
||||
ParameterPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Object",
|
||||
parameterName: "data",
|
||||
customUserInput: `{{} "openapiIsCool": true }`,
|
||||
customExpectedUrlSubstring: "?openapiIsCool=true",
|
||||
exampleA: {
|
||||
key: "ObjectExampleA",
|
||||
serializedValue:
|
||||
"firstName=Kyle&lastName=Shockey&email=kyle.shockey%40smartbear.com",
|
||||
value: JSON.stringify(
|
||||
{
|
||||
firstName: "Kyle",
|
||||
lastName: "Shockey",
|
||||
email: "kyle.shockey@smartbear.com",
|
||||
},
|
||||
null,
|
||||
2
|
||||
),
|
||||
},
|
||||
exampleB: {
|
||||
key: "ObjectExampleB",
|
||||
serializedValue:
|
||||
"name=Abbey&type=kitten&color=calico&gender=female&age=11%20weeks",
|
||||
value: JSON.stringify(
|
||||
{
|
||||
name: "Abbey",
|
||||
type: "kitten",
|
||||
color: "calico",
|
||||
gender: "female",
|
||||
age: "11 weeks",
|
||||
},
|
||||
null,
|
||||
2
|
||||
),
|
||||
},
|
||||
})
|
||||
})
|
||||
describe("in a Request Body", () => {
|
||||
const exampleA = JSON.stringify(
|
||||
{
|
||||
firstName: "Kyle",
|
||||
lastName: "Shockey",
|
||||
email: "kyle.shockey@smartbear.com",
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
const exampleB = JSON.stringify(
|
||||
{
|
||||
name: "Abbey",
|
||||
type: "kitten",
|
||||
color: "calico",
|
||||
gender: "female",
|
||||
age: "11 weeks",
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
RequestBodyPrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Object",
|
||||
primaryMediaType: "application/json",
|
||||
// ↓ not a typo, Cypress requires escaping { when using `cy.type`
|
||||
customUserInput: `{{} "openapiIsCool": true }`,
|
||||
customExpectedUrlSubstring: "?openapiIsCool=true",
|
||||
customUserInputExpectedCurlSubstring: `{ "openapiIsCool": true }`,
|
||||
exampleA: {
|
||||
key: "ObjectExampleA",
|
||||
serializedValue: exampleA,
|
||||
value: exampleA,
|
||||
summary: "A user's contact info",
|
||||
},
|
||||
exampleB: {
|
||||
key: "ObjectExampleB",
|
||||
serializedValue: exampleB,
|
||||
value: exampleB,
|
||||
summary: "A wonderful kitten's info",
|
||||
},
|
||||
})
|
||||
it("should display an error message when input validation fails", () => {
|
||||
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
|
||||
// Expand the operation
|
||||
.get("#operations-default-post_Object")
|
||||
.click()
|
||||
// Switch to Try-It-Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Set an invalid value
|
||||
.get(".parameters-container > div > table > tbody > tr > td.parameters-col_description > div:nth-child(2) > textarea")
|
||||
.type("{{{{ [[[[ <<<< invalid JSON here.")
|
||||
// Execute the operation
|
||||
.get(".execute")
|
||||
.click()
|
||||
// Verify that an error is shown
|
||||
.get(".validation-errors")
|
||||
.contains("Parameter string value must be valid JSON")
|
||||
})
|
||||
})
|
||||
describe("in a Response", () => {
|
||||
ResponsePrimitiveTestCases({
|
||||
operationDomId: "#operations-default-post_Object",
|
||||
exampleA: {
|
||||
key: "ObjectExampleA",
|
||||
value: JSON.stringify(
|
||||
{
|
||||
firstName: "Kyle",
|
||||
lastName: "Shockey",
|
||||
email: "kyle.shockey@smartbear.com",
|
||||
},
|
||||
null,
|
||||
2
|
||||
),
|
||||
summary: "A user's contact info",
|
||||
},
|
||||
exampleB: {
|
||||
key: "ObjectExampleB",
|
||||
value: JSON.stringify(
|
||||
{
|
||||
name: "Abbey",
|
||||
type: "kitten",
|
||||
color: "calico",
|
||||
gender: "female",
|
||||
age: "11 weeks",
|
||||
},
|
||||
null,
|
||||
2
|
||||
),
|
||||
summary: "A wonderful kitten's info",
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,184 @@
|
||||
// https://github.com/swagger-api/swagger-ui/issues/6201
|
||||
// https://github.com/swagger-api/swagger-ui/issues/6250
|
||||
// https://github.com/swagger-api/swagger-ui/issues/6476
|
||||
|
||||
describe("OpenAPI 3.0 Multiple Media Types with different schemas", () => {
|
||||
const mediaTypeFormData = "multipart/form-data"
|
||||
const mediaTypeUrlencoded = "application/x-www-form-urlencoded"
|
||||
const mediaTypeJson = "application/json"
|
||||
|
||||
beforeEach(() => {
|
||||
cy.intercept({
|
||||
method: "POST",
|
||||
url: "/post",
|
||||
hostname: "httpbin.org",
|
||||
}, {})
|
||||
|
||||
cy.visit(
|
||||
"/?url=/documents/features/oas3-multiple-media-type.yaml"
|
||||
)
|
||||
.get("#operations-default-post_post")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// @alias Execute Button
|
||||
cy.get(".execute.opblock-control__btn").as("executeBtn")
|
||||
// @alias Media Type Dropdown
|
||||
cy.get(".opblock-section-request-body .content-type").as("selectMediaType")
|
||||
})
|
||||
|
||||
// In all cases,
|
||||
// - assume that examples are populated based on schema (not explicitly tested)
|
||||
// - assume validation passes based on successful "execute"
|
||||
// - expect final cURL command result doees not contain unexpected artifacts from other content-type schemas
|
||||
describe("multipart/form-data (only 'bar')", () => {
|
||||
it("should execute multipart/form-data", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeUrlencoded)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeFormData)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "bar")
|
||||
.should("not.contains.text", "foo")
|
||||
})
|
||||
it("should execute application/x-www-form-urlencoded THEN execute multipart/form-data", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeUrlencoded)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeFormData)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "bar")
|
||||
.should("not.contains.text", "foo")
|
||||
})
|
||||
it("should execute application/json THEN execute multipart/form-data", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeJson)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeFormData)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "bar")
|
||||
.should("not.contains.text", "foo")
|
||||
})
|
||||
})
|
||||
|
||||
describe("application/x-www-form-urlencoded (only 'foo')", () => {
|
||||
it("should execute application/x-www-form-urlencoded", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeUrlencoded)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "foo")
|
||||
.should("not.contains.text", "bar")
|
||||
})
|
||||
it("should execute multipart/form-data THEN execute application/x-www-form-urlencoded", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeFormData)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeUrlencoded)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "foo")
|
||||
.should("not.contains.text", "bar")
|
||||
})
|
||||
it("should execute application/json THEN execute application/x-www-form-urlencoded", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeJson)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeUrlencoded)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "foo")
|
||||
.should("not.contains.text", "bar")
|
||||
})
|
||||
})
|
||||
|
||||
describe("application/json (both 'foo' and 'bar')", () => {
|
||||
// note: form input for "application/json" is a string; not multiple form fields
|
||||
it("should execute application/json", () => {
|
||||
// final curl should have both "bar" and "foo"
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeJson)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "foo")
|
||||
.should("contains.text", "bar")
|
||||
})
|
||||
it("should execute multipart/form-data THEN execute application/json", () => {
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeFormData)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeJson)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "foo")
|
||||
.should("contains.text", "bar")
|
||||
})
|
||||
it("should execute application/x-www-form-urlencoded THEN execute application/json", () => {
|
||||
// final curl should have both "bar" and "foo"
|
||||
cy.get("@selectMediaType")
|
||||
.select(mediaTypeUrlencoded)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
.get("@selectMediaType")
|
||||
.select(mediaTypeJson)
|
||||
.get("@executeBtn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "foo")
|
||||
.should("contains.text", "bar")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 Multiple Servers", () => {
|
||||
it("should render and execute for server '/test-url-1'", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/oas3-multiple-servers.yaml"
|
||||
)
|
||||
.get(".scheme-container .schemes .servers label > select")
|
||||
.select("/test-url-1")
|
||||
.get("#operations-default-get_")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(".responses-wrapper .request-url")
|
||||
.should("contains.text", "/test-url-1")
|
||||
})
|
||||
it("should render and execute for server '/test-url-2'", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/oas3-multiple-servers.yaml"
|
||||
)
|
||||
.get(".scheme-container .schemes .servers label > select")
|
||||
.select("/test-url-2")
|
||||
.get("#operations-default-get_")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(".responses-wrapper .request-url")
|
||||
.should("contains.text", "/test-url-2")
|
||||
})
|
||||
it("should render and execute for server '/test-url-1' after sequence: select '/test-url-2' -> Try-It-Out -> select '/test-url-1'", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/oas3-multiple-servers.yaml"
|
||||
)
|
||||
.get(".scheme-container .schemes .servers label > select")
|
||||
.select("/test-url-2")
|
||||
.get("#operations-default-get_")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Select a different server
|
||||
.get(".scheme-container .schemes .servers label > select")
|
||||
.select("/test-url-1")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(".responses-wrapper .request-url")
|
||||
.should("contains.text", "/test-url-1")
|
||||
})
|
||||
it("should render and execute for server '/test-url-switch-1' after changing api definition", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/oas3-multiple-servers.yaml"
|
||||
)
|
||||
.get(".scheme-container .schemes .servers label > select")
|
||||
.select("/test-url-2")
|
||||
cy.visit(
|
||||
"/?url=/documents/features/oas3-multiple-servers-switch.yaml"
|
||||
)
|
||||
.get(".scheme-container .schemes .servers label > select")
|
||||
.select("/test-url-switch-2")
|
||||
.get("#operations-default-get_")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(".responses-wrapper .request-url")
|
||||
.should("contains.text", "/test-url-switch-2")
|
||||
})
|
||||
})
|
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 Allow Empty Values in Request Body", () => {
|
||||
it("should not apply or render to required fields", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("not.exist")
|
||||
})
|
||||
|
||||
it("by default, should be checked for all non-required fields", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("be.checked")
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(6) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("be.checked")
|
||||
})
|
||||
|
||||
it("checkbox should be toggle-able", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("be.checked")
|
||||
.uncheck()
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.should("not.be.checked")
|
||||
})
|
||||
|
||||
it("on execute, should allow send with all empty values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// add item to pass required validation
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description button")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "tags=&status=")
|
||||
})
|
||||
|
||||
it("on execute, should allow send with some empty values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.uncheck()
|
||||
// add item to pass required validation
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description button")
|
||||
.click()
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) input")
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "&status=")
|
||||
.should("not.contains.text", "tags=")
|
||||
})
|
||||
|
||||
it("on execute, should allow send with skip all empty values", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml"
|
||||
)
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Request Body
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(5) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.uncheck()
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(6) > .parameters-col_description .parameter__empty_value_toggle input")
|
||||
.uncheck()
|
||||
// add item to pass required validation
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description button")
|
||||
.click()
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) input")
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// cURL component
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("not.contains.text", "tags=")
|
||||
.should("not.contains.text", "status=")
|
||||
})
|
||||
|
||||
})
|
@ -0,0 +1,16 @@
|
||||
describe("OAS3 default views", () => {
|
||||
describe("multipart/form-data", () => {
|
||||
it("should display calculated object string, when no examples provided (#7268)", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/request-body/multipart/default-views.yaml",
|
||||
)
|
||||
.get("#operations-default-post_test")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description textarea")
|
||||
.should("contains.text", "\"stuff\": \"string\"")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 Validation for Required Request Body and Request Body Fields", () => {
|
||||
describe("Request Body required bug/5181", () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept(
|
||||
{
|
||||
method: "POST",
|
||||
url: "/anything/foos",
|
||||
hostname: "httpbin.org",
|
||||
},
|
||||
{}
|
||||
)
|
||||
})
|
||||
|
||||
it("on execute, if empty value, SHOULD render class 'invalid' and should NOT render cURL component", () => {
|
||||
cy.visit("/?url=/documents/bugs/5181.yaml")
|
||||
.get("#operations-default-post_foos")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get input
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(1) > .parameters-col_description input"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// class "invalid" should now exist (and render red, which we won't check)
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(1) > .parameters-col_description input"
|
||||
)
|
||||
.should("have.class", "invalid")
|
||||
// cURL component should not exist
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("on execute, if value exists, should NOT render class 'invalid' and SHOULD render cURL component", () => {
|
||||
cy.visit("/?url=/documents/bugs/5181.yaml")
|
||||
.get("#operations-default-post_foos")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get input
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(1) > .parameters-col_description input"
|
||||
)
|
||||
.type("abc")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(1) > .parameters-col_description input"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
// cURL component should exist
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Request Body required fields - application/json", () => {
|
||||
it("on execute, if empty value, SHOULD render class 'invalid' and should NOT render cURL component", () => {
|
||||
cy.visit("/?url=/documents/features/petstore-only-pet.openapi.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get and clear textarea
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// class "invalid" should now exist (and render red, which we won't check)
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.should("have.class", "invalid")
|
||||
// cURL component should not exist
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("on execute, if value exists, even if just single space, should NOT render class 'invalid' and SHOULD render cURL component that contains the single space", () => {
|
||||
cy.visit("/?url=/documents/features/petstore-only-pet.openapi.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get, clear, then modify textarea
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.clear()
|
||||
.type(" ")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
// cURL component should exist
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "' '")
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
petstore ux notes:
|
||||
- required field, but if example value exists, will populate the field. So this test will clear the example value.
|
||||
- "add item" will insert an empty array, and display an input text box. This establishes a value for the field.
|
||||
*/
|
||||
describe("Request Body required fields - application/x-www-form-urlencoded", () => {
|
||||
it("on execute, if empty value, SHOULD render class 'invalid' and should NOT render cURL component", () => {
|
||||
cy.visit("/?url=/documents/features/petstore-only-pet.openapi.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-section .opblock-section-request-body .body-param-content-type > select"
|
||||
)
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get and clear input populated from example value
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description input"
|
||||
)
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// class "invalid" should now exist (and render red, which we won't check)
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description input"
|
||||
)
|
||||
.should("have.class", "invalid")
|
||||
// cURL component should not exist
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("on execute, if all values exist, even if array exists but is empty, should NOT render class 'invalid' and SHOULD render cURL component", () => {
|
||||
cy.visit("/?url=/documents/features/petstore-only-pet.openapi.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-section .opblock-section-request-body .body-param-content-type > select"
|
||||
)
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// add item to get input
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description button"
|
||||
)
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description input"
|
||||
)
|
||||
.should("have.value", "doggie")
|
||||
.should("not.have.class", "invalid")
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description input"
|
||||
)
|
||||
.should("have.value", "string")
|
||||
.should("not.have.class", "invalid")
|
||||
// cURL component should exist
|
||||
.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
||||
|
||||
describe("Request Body: switching between Content Types", () => {
|
||||
it("after application/json 'invalid' error, on switch content type to application/x-www-form-urlencoded, SHOULD be free of errors", () => {
|
||||
cy.visit("/?url=/documents/features/petstore-only-pet.openapi.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get and clear textarea
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.should("have.class", "invalid")
|
||||
// switch content type
|
||||
.get(
|
||||
".opblock-section .opblock-section-request-body .body-param-content-type > select"
|
||||
)
|
||||
.select("application/x-www-form-urlencoded")
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description input"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
// add item to get input, just an extra confirmation of non-invalid class
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description button"
|
||||
)
|
||||
.click()
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(4) > .parameters-col_description input"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
})
|
||||
it("after application/x-www-form-urlencoded 'invalid' error, on switch content type to application/json, SHOULD be free of errors", () => {
|
||||
cy.visit("/?url=/documents/features/petstore-only-pet.openapi.yaml")
|
||||
.get("#operations-pet-addPet")
|
||||
.click()
|
||||
.get(
|
||||
".opblock-section .opblock-section-request-body .body-param-content-type > select"
|
||||
)
|
||||
.select("application/x-www-form-urlencoded")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// get and clear input
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description input"
|
||||
)
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// class "invalid" should now exist (and render red, which we won't check)
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .parameters:nth-child(2) > .parameters-col_description input"
|
||||
)
|
||||
.should("have.class", "invalid")
|
||||
// switch content type
|
||||
.get(
|
||||
".opblock-section .opblock-section-request-body .body-param-content-type > select"
|
||||
)
|
||||
.select("application/json")
|
||||
.get(
|
||||
".opblock-body .opblock-section .opblock-section-request-body .body-param textarea"
|
||||
)
|
||||
.should("not.have.class", "invalid")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,106 @@
|
||||
function getExpandedTryout(page = null, operationId = "#operations-pet-addPet") {
|
||||
return (page || cy.visit(
|
||||
"/?url=/documents/features/petstore-only-pet.openapi.yaml",
|
||||
))
|
||||
.get(operationId)
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
}
|
||||
|
||||
const getRequestBodyFromCY = (page = null, operationId = "#operations-pet-addPet") =>
|
||||
getExpandedTryout(page, operationId)
|
||||
// get textarea
|
||||
.get(".opblock-body .opblock-section .opblock-section-request-body .body-param textarea")
|
||||
|
||||
const xmlIndicator = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
const userEditXmlSample = xmlIndicator +
|
||||
"<pet>\n" +
|
||||
"\t<id>420</id>\n" +
|
||||
"\t<name>doggie<3</name>\n" +
|
||||
"\t<category>\n" +
|
||||
"\t\t<id>99999999999</id>\n" +
|
||||
"\t\t<name>Dogiiiiiiiieeee</name>\n" +
|
||||
"\t</category>\n" +
|
||||
"\t<photoUrls>\n" +
|
||||
"\t\t<photoUrl>string</photoUrl>\n" +
|
||||
"\t</photoUrls>\n" +
|
||||
"\t<tags>\n" +
|
||||
"\t\t<tag>\n" +
|
||||
"\t\t\t<id>0</id>\n" +
|
||||
"\t\t\t<name>string</name>\n" +
|
||||
"\t\t</tag>\n" +
|
||||
"\t</tags>\n" +
|
||||
"\t<status>available</status>\n" +
|
||||
"</pet>"
|
||||
|
||||
describe("OAS3 Request Body user edit flows", () => {
|
||||
// Case: Copy xml from email, paste into request body editor, change media-type to xml
|
||||
it("it should never overwrite user edited value in case of media-type change", () => {
|
||||
getRequestBodyFromCY()
|
||||
// replace default sample with xml edited value
|
||||
.type(`{selectall}${userEditXmlSample}`)
|
||||
// change media type to xml, because I have forgotten it
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/xml")
|
||||
// Ensure user edited body is not overwritten
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get("textarea")
|
||||
.should(($div) => {
|
||||
expect($div.get(0).textContent).to.eq(userEditXmlSample)
|
||||
})
|
||||
})
|
||||
})
|
||||
// Case: User really wants to try out the brand new xml content-type
|
||||
it("it should overwrite default value in case of content-type change, even within request body editor(#6836)", () => {
|
||||
getRequestBodyFromCY()
|
||||
// change media type to xml, because I have forgotten it (sry really wanted to try out the new xml content-type)
|
||||
.get(".opblock-section .opblock-section-request-body .body-param-content-type > select")
|
||||
.select("application/xml")
|
||||
// Ensure default value is xml after content type change
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get("textarea")
|
||||
.should(($div) => {
|
||||
expect($div.get(0).textContent).to.contain(xmlIndicator)
|
||||
})
|
||||
})
|
||||
})
|
||||
// Case: User wants to get the default value back
|
||||
it("it reset the user edited value and render the default value in case of try out reset. (#6517)", () => {
|
||||
getRequestBodyFromCY()
|
||||
// replace default sample with bad value
|
||||
.type("{selectall}ups that should not have happened")
|
||||
// Cancel Try It Out
|
||||
.get(".try-out__btn.reset")
|
||||
.click()
|
||||
// Ensure default value is xml after content type change
|
||||
.get(".opblock-section-request-body")
|
||||
.within(() => {
|
||||
cy
|
||||
.get("textarea")
|
||||
.should(($div) => {
|
||||
expect($div.get(0).textContent).to.not.contain("ups that should not have happened")
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("multipart/", () => {
|
||||
// Case: User wants to execute operation with media-type multipart/ with a enum property. The user expects the first enum value to be used when executed.
|
||||
it("should use the first enum value on execute if not changed by user (#6976)", () => {
|
||||
// test/e2e-cypress/static/documents/features/request-body/multipart/enum.yaml
|
||||
getExpandedTryout(
|
||||
cy.visit(
|
||||
"/?url=/documents/features/request-body/multipart/enum.yaml",
|
||||
), "#operations-default-post_test")
|
||||
.get(".execute")
|
||||
.click()
|
||||
// Assert on the request URL
|
||||
.get(".curl")
|
||||
.contains("test_enum=A")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,70 @@
|
||||
describe("XML schema rendering examples", () => {
|
||||
it("Should render RequestBody example value when schema contains `oneOf` for mediaType `text/xml`", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_foo")
|
||||
.click()
|
||||
.get("label > .content-type-wrapper > .content-type option:selected")
|
||||
.should("have.text", "text/xml")
|
||||
.get(".body-param__example")
|
||||
.should("contains.text", "<fooOne>")
|
||||
})
|
||||
it("Should render RequestBody example value when schema contains `anyOf` for mediaType `text/xml`", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_bar")
|
||||
.click()
|
||||
.get("label > .content-type-wrapper > .content-type option:selected")
|
||||
.should("have.text", "text/xml")
|
||||
.get(".body-param__example")
|
||||
.should("contains.text", "<fooOne>")
|
||||
})
|
||||
it("Should render RequestBody example value when schema contains `oneOf` for mediaType `application/xml`", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_foobar")
|
||||
.click()
|
||||
.get("label > .content-type-wrapper > .content-type option:selected")
|
||||
.should("have.text", "application/xml")
|
||||
.get(".body-param__example")
|
||||
.should("contains.text", "<fooOne>")
|
||||
})
|
||||
it("Should render RequestBody example value when schema contains `anyOf` for mediaType `application/xml`", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_barfoo")
|
||||
.click()
|
||||
.get("label > .content-type-wrapper > .content-type option:selected")
|
||||
.should("have.text", "application/xml")
|
||||
.get(".body-param__example")
|
||||
.should("contains.text", "<fooOne>")
|
||||
})
|
||||
it("Should render RequestBody example value when switching mediaType to `text/xml` with singular content schema", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_barfoo")
|
||||
.click()
|
||||
.get("label > .content-type-wrapper > .content-type")
|
||||
.select("text/xml")
|
||||
.get(".body-param__example")
|
||||
.should("contains.text", "<fooThree>")
|
||||
})
|
||||
it("Should render RequestBody example value when switching mediaType to `application/xml` with singular content schema", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_foo")
|
||||
.click()
|
||||
.get("label > .content-type-wrapper > .content-type")
|
||||
.select("application/xml")
|
||||
.get(".body-param__example")
|
||||
.should("contains.text", "<fooTwo>")
|
||||
})
|
||||
it("Should render Response example value for mediaType `application/xml`", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_foo")
|
||||
.click()
|
||||
.get(".response-col_description > .model-example")
|
||||
.should("contains.text", "<foobarResObj>")
|
||||
})
|
||||
it("Should render Response example value for mediaType `text/xml`", () => {
|
||||
cy.visit("?url=/documents/features/oas3-xml.json")
|
||||
.get("#operations-default-post_foobar")
|
||||
.click()
|
||||
.get(".response-col_description > .model-example")
|
||||
.should("contains.text", "<foobarResObj>")
|
||||
})
|
||||
})
|
@ -0,0 +1,66 @@
|
||||
describe("OAuth2 Application flow", function() {
|
||||
beforeEach(() => {
|
||||
cy.server()
|
||||
cy.route({
|
||||
url: "**/oauth/*",
|
||||
method: "POST"
|
||||
}).as("tokenRequest")
|
||||
})
|
||||
|
||||
// https://github.com/swagger-api/swagger-ui/issues/6395
|
||||
it("should have first authorization input autofocused", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
cy.focused()
|
||||
.should("have.id", "oauth_username")
|
||||
})
|
||||
|
||||
it("should make an application flow Authorization header request", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
.get("div.modal-ux-content > div:nth-child(2)").within(() => {
|
||||
cy.get("#client_id")
|
||||
.clear()
|
||||
.type("confidentialApplication")
|
||||
|
||||
.get("#client_secret")
|
||||
.clear()
|
||||
.type("topSecret")
|
||||
|
||||
.get("button.btn.modal-btn.auth.authorize.button")
|
||||
.click()
|
||||
})
|
||||
|
||||
cy.get("button.close-modal")
|
||||
.click()
|
||||
|
||||
.get("#operations-default-get_application")
|
||||
.click()
|
||||
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("body")
|
||||
.should("equal", "grant_type=client_credentials")
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.its("authorization")
|
||||
.should("equal", "Basic Y29uZmlkZW50aWFsQXBwbGljYXRpb246dG9wU2VjcmV0")
|
||||
|
||||
.get(".live-responses-table .response-col_status")
|
||||
.contains("200")
|
||||
})
|
||||
})
|
@ -0,0 +1,122 @@
|
||||
describe("OAuth2 Password flow", function() {
|
||||
beforeEach(() => {
|
||||
cy.server()
|
||||
cy.route({
|
||||
url: "**/oauth/*",
|
||||
method: "POST"
|
||||
}).as("tokenRequest")
|
||||
})
|
||||
|
||||
it("should make a password flow Authorization header request", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
.get("#oauth_username")
|
||||
.type("swagger")
|
||||
|
||||
.get("#oauth_password")
|
||||
.type("password")
|
||||
|
||||
.get("#password_type")
|
||||
.select("basic")
|
||||
|
||||
.get("#client_id")
|
||||
.clear()
|
||||
.type("application")
|
||||
|
||||
.get("#client_secret")
|
||||
.clear()
|
||||
.type("secret")
|
||||
|
||||
.get("div.modal-ux-content > div:nth-child(1) > div > div:nth-child(2) > div > div.auth-btn-wrapper > button.btn.modal-btn.auth.authorize.button")
|
||||
.click()
|
||||
|
||||
.get("button.close-modal")
|
||||
.click()
|
||||
|
||||
.get("#operations-default-get_password")
|
||||
.click()
|
||||
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("body")
|
||||
.should("include", "grant_type=password")
|
||||
.should("include", "username=swagger")
|
||||
.should("include", "password=password")
|
||||
.should("not.include", "client_id")
|
||||
.should("not.include", "client_secret")
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.its("authorization")
|
||||
.should("equal", "Basic YXBwbGljYXRpb246c2VjcmV0")
|
||||
|
||||
.get(".live-responses-table .response-col_status")
|
||||
.contains("200")
|
||||
})
|
||||
|
||||
it("should make a Password flow request-body request", () => {
|
||||
cy
|
||||
.visit("/?url=http://localhost:3231/swagger.yaml")
|
||||
.get(".btn.authorize")
|
||||
.click()
|
||||
|
||||
.get("#oauth_username")
|
||||
.type("swagger")
|
||||
|
||||
.get("#oauth_password")
|
||||
.type("password")
|
||||
|
||||
.get("#password_type")
|
||||
.select("request-body")
|
||||
|
||||
.get("#client_id")
|
||||
.clear()
|
||||
.type("application")
|
||||
|
||||
.get("#client_secret")
|
||||
.clear()
|
||||
.type("secret")
|
||||
|
||||
.get("div.modal-ux-content > div:nth-child(1) > div > div:nth-child(2) > div > div.auth-btn-wrapper > button.btn.modal-btn.auth.authorize.button")
|
||||
.click()
|
||||
|
||||
.get("button.close-modal")
|
||||
.click()
|
||||
|
||||
.get("#operations-default-get_password")
|
||||
.click()
|
||||
|
||||
.get(".btn.try-out__btn")
|
||||
.click()
|
||||
|
||||
.get(".btn.execute")
|
||||
.click()
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("body")
|
||||
.should("include", "grant_type=password")
|
||||
.should("include", "username=swagger")
|
||||
.should("include", "password=password")
|
||||
.should("include", "client_id=application")
|
||||
.should("include", "client_secret=secret")
|
||||
|
||||
cy.get("@tokenRequest")
|
||||
.its("request")
|
||||
.its("headers")
|
||||
.should("not.have.property", "authorization")
|
||||
|
||||
.get(".live-responses-table .response-col_status")
|
||||
.contains("200")
|
||||
})
|
||||
})
|
@ -0,0 +1,10 @@
|
||||
describe("Parameter - Invalid definition with missing array 'items' (#7375)", () => {
|
||||
it("should render gracefully with fallback to default value", () => {
|
||||
cy.visit("/?url=/documents/features/parameter-array-missing-items.yaml")
|
||||
.get("#operations-default-get_example1")
|
||||
.click()
|
||||
.get("tbody > tr > .parameters-col_description textarea")
|
||||
.should("exist")
|
||||
.should("contains.text", "{}")
|
||||
})
|
||||
})
|
@ -0,0 +1,30 @@
|
||||
describe("Parameter order", () => {
|
||||
|
||||
it("should be well ordered", () => {
|
||||
cy.visit("/?url=/documents/features/parameter-order.yaml")
|
||||
.get("#operations-default-post_test__id__related__relatedId_")
|
||||
.click()
|
||||
.get(".parameters > tbody")
|
||||
.children()
|
||||
.each((tr, i, arr) => {
|
||||
const parameterTableRows = Array.from(arr)
|
||||
expect(tr).to.have.attr("data-param-in")
|
||||
if (i === 0) {
|
||||
return
|
||||
}
|
||||
const inValue = tr[0].getAttribute("data-param-in")
|
||||
if (!inValue) {
|
||||
return
|
||||
}
|
||||
const beforeInValue = parameterTableRows[i - 1].getAttribute("data-param-in")
|
||||
const sameAsBefore = beforeInValue === inValue
|
||||
if (sameAsBefore) {
|
||||
expect(parameterTableRows[i - 1]).to.have.attr("data-param-in", inValue)
|
||||
return
|
||||
}
|
||||
for (let x = i + 1; x < parameterTableRows.length; x++) {
|
||||
expect(parameterTableRows[x]).to.not.have.attr("data-param-in", beforeInValue)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,23 @@
|
||||
describe("Loading specs by url.primaryName param", () => {
|
||||
describe("with no param", () => {
|
||||
it("should load the default spec", () => {
|
||||
cy.visit("/pages/multiple-urls/index.html")
|
||||
.get("span.url")
|
||||
.contains("/documents/petstore-expanded.openapi.yaml")
|
||||
})
|
||||
})
|
||||
describe("with an invalid param", () => {
|
||||
it("should fall back to the default spec", () => {
|
||||
cy.visit("/pages/multiple-urls/index.html?urls.primaryName=undefinedUrlName")
|
||||
.get("span.url")
|
||||
.contains("/documents/petstore-expanded.openapi.yaml")
|
||||
})
|
||||
})
|
||||
describe("with a valid url.primaryName param", () => {
|
||||
it("should render the requested spec", () => {
|
||||
cy.visit("/pages/multiple-urls/index.html?urls.primaryName=Petstore Swagger")
|
||||
.get("span.url")
|
||||
.contains("/documents/petstore.swagger.yaml")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 Request Body upload file button", () => {
|
||||
describe("application/octet-stream", () => {
|
||||
it("should display description with the correct content type", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadApplicationOctetStream")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||
.should("have.text", "Example values are not available for application/octet-stream media types.")
|
||||
})
|
||||
it("should display a file upload button", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadApplicationOctetStream")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||
.should("have.prop", "type", "file")
|
||||
})
|
||||
})
|
||||
describe("image/png", () => {
|
||||
it("should display description with the correct content type", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadImagePng")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||
.should("have.text", "Example values are not available for image/png media types.")
|
||||
})
|
||||
it("should display a file upload button", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadApplicationOctetStream")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||
.should("have.prop", "type", "file")
|
||||
})
|
||||
})
|
||||
describe("audio/wav", () => {
|
||||
it("should display description with the correct content type", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadAudioWav")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||
.should("have.text", "Example values are not available for audio/wav media types.")
|
||||
})
|
||||
it("should display a file upload button", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadApplicationOctetStream")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||
.should("have.prop", "type", "file")
|
||||
})
|
||||
})
|
||||
describe("video/mpeg", () => {
|
||||
it("should display description with the correct content type", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadVideoMpeg")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||
.should("have.text", "Example values are not available for video/mpeg media types.")
|
||||
})
|
||||
it("should display a file upload button", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadApplicationOctetStream")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||
.should("have.prop", "type", "file")
|
||||
})
|
||||
})
|
||||
describe("schema format binary", () => {
|
||||
it("should display description with the correct content type", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadSchemaFormatBinary")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||
.should("have.text", "Example values are not available for application/x-custom media types.")
|
||||
})
|
||||
it("should display a file upload button", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadSchemaFormatBinary")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||
.should("have.prop", "type", "file")
|
||||
})
|
||||
})
|
||||
describe("schema format base64", () => {
|
||||
it("should display description with the correct content type", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadSchemaFormatBase64")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper i")
|
||||
.should("have.text", "Example values are not available for application/x-custom media types.")
|
||||
})
|
||||
it("should display a file upload button", () => {
|
||||
cy.visit("/?url=/documents/features/request-body-upload-file.yaml")
|
||||
.get("#operations-default-uploadSchemaFormatBinary")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".opblock-section-request-body .opblock-description-wrapper input")
|
||||
.should("have.prop", "type", "file")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,49 @@
|
||||
describe("Response extension feature", () => {
|
||||
describe("in Swagger 2", () => {
|
||||
const swagger2BaseUrl = "/?showExtensions=true&docExpansion=full&url=/documents/features/response-extension.swagger.yaml"
|
||||
|
||||
describe("without x- values", () => {
|
||||
it("should omit response extensions section", () => {
|
||||
cy.visit(swagger2BaseUrl)
|
||||
.get("tr.response[data-code='200'] td.response-col_description div.response__extension")
|
||||
.should("not.exist")
|
||||
})
|
||||
})
|
||||
|
||||
describe("with x- values", () => {
|
||||
it("should list each value", () => {
|
||||
const page = cy.visit(swagger2BaseUrl)
|
||||
|
||||
page.get("tr.response[data-code='404'] td.response-col_description div.response__extension:nth-child(2)")
|
||||
.should("have.text", "x-error: true")
|
||||
|
||||
page.get("tr.response[data-code='404'] td.response-col_description div.response__extension:nth-child(3)")
|
||||
.should("have.text", "x-error-codes: List [ \"NOT_FOUND\" ]")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("in OpenAPI 3", () => {
|
||||
const openAPI3BaseUrl = "/?showExtensions=true&docExpansion=full&url=/documents/features/response-extension.openapi.yaml"
|
||||
|
||||
describe("without x- values", () => {
|
||||
it("should omit response extensions section", () => {
|
||||
cy.visit(openAPI3BaseUrl)
|
||||
.get("tr.response[data-code='200'] td.response-col_description div.response__extension")
|
||||
.should("not.exist")
|
||||
})
|
||||
})
|
||||
|
||||
describe("with x- values", () => {
|
||||
it("should list each value", () => {
|
||||
const page = cy.visit(openAPI3BaseUrl)
|
||||
|
||||
page.get("tr.response[data-code='404'] td.response-col_description div.response__extension:nth-child(2)")
|
||||
.should("have.text", "x-error: true")
|
||||
|
||||
page.get("tr.response[data-code='404'] td.response-col_description div.response__extension:nth-child(3)")
|
||||
.should("have.text", "x-error-codes: List [ \"NOT_FOUND\" ]")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,129 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("JSON Schema Form: Enum & Boolean in a Parameter", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/schema-form-enum-boolean.yaml"
|
||||
)
|
||||
.get("#operations-pet-findPetsByStatus")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// @alias Execute Button
|
||||
cy.get(".execute.opblock-control__btn").as("executeBtn")
|
||||
// @alias Parameters
|
||||
cy.get(".opblock-section tbody > tr > .parameters-col_description > select")
|
||||
.eq(0)
|
||||
.as("enumIsRequired")
|
||||
cy.get(".opblock-section tbody > tr > .parameters-col_description > select")
|
||||
.eq(1)
|
||||
.as("booleanIsOptional")
|
||||
cy.get(".opblock-section tbody > tr > .parameters-col_description > select")
|
||||
.eq(2)
|
||||
.as("booleanIsRequired")
|
||||
})
|
||||
|
||||
it("should render @enumIsRequired with list of three options", () => {
|
||||
cy.get("@enumIsRequired")
|
||||
.should("contains.text", "available")
|
||||
.should("contains.text", "pending")
|
||||
.should("contains.text", "sold")
|
||||
.should("not.contains.text", "--")
|
||||
.find("option")
|
||||
.should("have.length", 3)
|
||||
})
|
||||
it("should render @booleanIsOptional with default empty string value (display '--')", () => {
|
||||
cy.get("@booleanIsOptional")
|
||||
.should("have.value", "")
|
||||
.should("contains.text", "--")
|
||||
})
|
||||
it("should render @booleanIsRequired with default empty string value (display '--')", () => {
|
||||
cy.get("@booleanIsRequired")
|
||||
.should("have.value", "")
|
||||
.should("contains.text", "--")
|
||||
})
|
||||
it("should NOT be able to execute with empty @enumIsRequired and @booleanIsRequired values", () => {
|
||||
// Execute
|
||||
cy.get("@executeBtn")
|
||||
.click()
|
||||
cy.get("@enumIsRequired")
|
||||
.should("have.class", "invalid")
|
||||
cy.get("@booleanIsRequired")
|
||||
.should("have.class", "invalid")
|
||||
// cURL component
|
||||
cy.get(".responses-wrapper .curl-command")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("should NOT be able to execute with empty @booleanIsRequired value, but valid @enumIsRequired", () => {
|
||||
cy.get("@enumIsRequired")
|
||||
.select("pending")
|
||||
// Execute
|
||||
cy.get("@executeBtn")
|
||||
.click()
|
||||
cy.get("@enumIsRequired")
|
||||
.should("not.have.class", "invalid")
|
||||
cy.get("@booleanIsRequired")
|
||||
.should("have.class", "invalid")
|
||||
// cURL component
|
||||
cy.get(".responses-wrapper .curl-command")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("should NOT be able to execute with empty @enumIsRequired value, but valid @booleanIsRequired", () => {
|
||||
cy.get("@booleanIsRequired")
|
||||
.select("false")
|
||||
// Execute
|
||||
cy.get("@executeBtn")
|
||||
.click()
|
||||
cy.get("@enumIsRequired")
|
||||
.should("have.class", "invalid")
|
||||
cy.get("@booleanIsRequired")
|
||||
.should("not.have.class", "invalid")
|
||||
// cURL component
|
||||
cy.get(".responses-wrapper .curl-command")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("should execute, if @booleanIsOptional value is 'false'", () => {
|
||||
cy.get("@enumIsRequired")
|
||||
.select("pending")
|
||||
cy.get("@booleanIsRequired")
|
||||
.select("false")
|
||||
cy.get("@booleanIsOptional")
|
||||
.select("false")
|
||||
// Execute
|
||||
cy.get("@executeBtn")
|
||||
.click()
|
||||
cy.get("@enumIsRequired")
|
||||
.should("not.have.class", "invalid")
|
||||
cy.get("@booleanIsRequired")
|
||||
.should("not.have.class", "invalid")
|
||||
.should("not.contains.text", "expectIsOptional")
|
||||
// cURL component
|
||||
cy.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("contains.text", "expectIsOptional=false")
|
||||
})
|
||||
it("should execute, but NOT send @booleanIsOptional value if not provided", () => {
|
||||
cy.get("@enumIsRequired")
|
||||
.select("pending")
|
||||
cy.get("@booleanIsRequired")
|
||||
.select("false")
|
||||
// Execute
|
||||
cy.get("@executeBtn")
|
||||
.click()
|
||||
cy.get("@enumIsRequired")
|
||||
.should("not.have.class", "invalid")
|
||||
cy.get("@booleanIsRequired")
|
||||
.should("not.have.class", "invalid")
|
||||
.should("not.contains.text", "expectIsOptional")
|
||||
// cURL component
|
||||
cy.get(".responses-wrapper .curl-command")
|
||||
.should("exist")
|
||||
.get(".responses-wrapper .curl-command span")
|
||||
.should("not.contains.text", "expectIsOptional")
|
||||
})
|
||||
|
||||
})
|
@ -0,0 +1,830 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("OpenAPI 3.0 Additional JsonSchemaForm in a Parameter", () => {
|
||||
describe("incomplete API definition with missing schema key or schema value(s)", () => {
|
||||
describe("parameter exists as global", () => {
|
||||
it("should render when parameter exists as global, but missing schema key", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_one_no_schema")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
it("should render when parameter exists as global, but missing all schema values", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_one_no_type_or_format")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
it("should render when parameter exists as global, schema key exists, but missing schema values: format", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_one_format_only_no_type")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
it("should render when parameter exists as global, schema key exists, but missing schema value: type", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_one_type_only_no_format")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
})
|
||||
describe("parameter exists in method", () => {
|
||||
it("should render when parameter exists in method, but missing schema key", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_two_no_schema")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
it("should render when parameter exists in method, schema key exists, but missing all schema values", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_two_no_type_or_format")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
it("should render when parameter exists in method, schema key exists, but missing schema value: format", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_one_type_only_no_format")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
it("should render when parameter exists in method, schema key exists, but missing schema value: type", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-missing-values.yaml")
|
||||
.get("#operations-default-get_case_one_format_only_no_type")
|
||||
.click()
|
||||
.get(".opblock-description .renderedMarkdown p")
|
||||
.should("have.text", "sf")
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("/Array", () => {
|
||||
describe("in a Parameter", () => {
|
||||
it("should allow modification of values in Try-It-Out", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}5")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
})
|
||||
it("should allow removal of added value in Try-It-Out", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}5")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
// Remove the last item that was just added
|
||||
.get(
|
||||
".json-schema-form-item:last-of-type > .json-schema-form-item-remove"
|
||||
)
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
])
|
||||
})
|
||||
})
|
||||
it("should allow removal of nth of values in Try-It-Out", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}5")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
])
|
||||
})
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.find(":selected")
|
||||
.should("have.text", "[Modified value]")
|
||||
// Remove the second item in list
|
||||
.get(
|
||||
".json-schema-form-item:nth-child(2) > .json-schema-form-item-remove"
|
||||
)
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"1",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
])
|
||||
})
|
||||
})
|
||||
it("should allow execution of operation in Try-It-Out", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
})
|
||||
it("should add empty item and allow execution of operation in Try-It-Out", () => {
|
||||
cy.visit(
|
||||
"/?url=/documents/features/multiple-examples-core.openapi.yaml"
|
||||
)
|
||||
.get("#operations-default-post_Array")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description .examples-select > select")
|
||||
.select("ArrayExampleB")
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
// Execute without prior typing a value
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("Petstore", () => {
|
||||
describe("/pet/findByStatus", () => {
|
||||
it("should render the operation, execute with default value", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-default-findPetsByStatus")
|
||||
.click()
|
||||
// Expand operation
|
||||
.get(".opblock-title span")
|
||||
.should("have.text", "Parameters")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "available")
|
||||
})
|
||||
it("should render the operation, modify value, and execute with modified value", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-default-findPetsByStatus")
|
||||
.click()
|
||||
// Expand operation
|
||||
.get(".opblock-title span")
|
||||
.should("have.text", "Parameters")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Select
|
||||
.get(".parameters-col_description > select")
|
||||
.select("pending")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "pending")
|
||||
})
|
||||
})
|
||||
describe("/pet/findByTags", () => {
|
||||
it("should allow modification of values in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.type("{selectall}spotted")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
])
|
||||
})
|
||||
})
|
||||
it("should allow removal of added value in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}spotted")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
])
|
||||
})
|
||||
// Remove the last item that was just added
|
||||
.get(
|
||||
".json-schema-form-item:last-of-type > .json-schema-form-item-remove"
|
||||
)
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.should("not.exist")
|
||||
})
|
||||
it("should allow removal of nth of values in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}spotted")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
])
|
||||
})
|
||||
// Add a 2nd new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}large")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
"large",
|
||||
])
|
||||
})
|
||||
// Add a 3rd new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}puppy")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
"large",
|
||||
"puppy",
|
||||
])
|
||||
})
|
||||
// Remove the second item in list
|
||||
.get(
|
||||
".json-schema-form-item:nth-child(2) > .json-schema-form-item-remove"
|
||||
)
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
"puppy",
|
||||
])
|
||||
})
|
||||
})
|
||||
it("should allow execution of operation without modifications in Try-It-Out (debounce)", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "findByTags")
|
||||
})
|
||||
it("should add empty item and allow execution of operation in Try-It-Out (debounce)", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
// Execute without prior typing a value
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "findByTags")
|
||||
})
|
||||
it("should add modified item and allow execution of operation in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.type("{selectall}spotted")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
])
|
||||
})
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "spotted")
|
||||
})
|
||||
it("should add 3 modified items, remove the middle child, and allow execution of operation Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-pet-findPetsByTags")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Add a new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}spotted")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
])
|
||||
})
|
||||
// Add a 2nd new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}large")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
"large",
|
||||
])
|
||||
})
|
||||
// Add a 3rd new item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > input")
|
||||
.type("{selectall}puppy")
|
||||
// Assert against the input fields
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
"large",
|
||||
"puppy",
|
||||
])
|
||||
})
|
||||
// Remove the second item in list
|
||||
.get(
|
||||
".json-schema-form-item:nth-child(2) > .json-schema-form-item-remove"
|
||||
)
|
||||
.click()
|
||||
.get(".json-schema-form-item > input")
|
||||
.then((inputs) => {
|
||||
expect(inputs.map((i, el) => el.value).toArray()).to.deep.equal([
|
||||
"spotted",
|
||||
"puppy",
|
||||
])
|
||||
})
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "tags=spotted&tags=puppy")
|
||||
.should("not.have.text", "large")
|
||||
})
|
||||
})
|
||||
describe("/petOwner/{petOwnerId}", () => {
|
||||
// This is a (GET) debounce test for schema type: string
|
||||
it("should render the operation, and allow execute of operation with empty value (debounce)", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-getPetOwnerById")
|
||||
.click()
|
||||
// Expand operation
|
||||
.get(".opblock-title span")
|
||||
.should("have.text", "Parameters")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "petOwner")
|
||||
})
|
||||
it("should render the operation, and input field, and allow execute of operation", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-getPetOwnerById")
|
||||
.click()
|
||||
// Expand operation
|
||||
.get(".opblock-title span")
|
||||
.should("have.text", "Parameters")
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".parameters-col_description > input")
|
||||
.type("123")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "petOwner")
|
||||
.should("contain.text", "123")
|
||||
})
|
||||
})
|
||||
describe("/petOwner/listOfServiceTrainer", () => {
|
||||
it("should allow execution of operation with value=true in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-listOfServiceTrainer")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// add 1st item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item > select")
|
||||
.select("true")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "tags=true")
|
||||
})
|
||||
it("should allow execution of operation with value=false in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-listOfServiceTrainer")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// add 1st item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item > select")
|
||||
.select("false")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "tags=false")
|
||||
})
|
||||
it("should allow execution of operation with value=true&value=false in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-listOfServiceTrainer")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// add 1st item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item > select")
|
||||
.select("true")
|
||||
// add 2nd item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > select")
|
||||
.select("false")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "tags=true&tags=false")
|
||||
})
|
||||
it("should allow execution of operation with value=false after removing value=true in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-listOfServiceTrainer")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// add 1st item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item > select")
|
||||
.select("true")
|
||||
// add 2nd item
|
||||
.get(".json-schema-form-item-add")
|
||||
.click()
|
||||
.get(".json-schema-form-item:last-of-type > select")
|
||||
.select("false")
|
||||
// remove 1st item
|
||||
.get(
|
||||
".json-schema-form-item:nth-child(1) > .json-schema-form-item-remove"
|
||||
)
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "tags=false")
|
||||
})
|
||||
it("should allow execution of operation with value=(empty) in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-listOfServiceTrainer")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "listOfServiceTrainer")
|
||||
})
|
||||
})
|
||||
describe("/petOwner/findByPreference", () => {
|
||||
it("should allow execution of operation with value=(empty) in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-findByPreference")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "findByPreference")
|
||||
})
|
||||
it("should allow execution of operation with selected value in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-findByPreference")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Select
|
||||
.get(".parameters-col_description > select")
|
||||
.select("dog")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "findByPreference")
|
||||
.should("contain.text", "dog")
|
||||
})
|
||||
it("should allow execution of operation with multiple selected values in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-findByPreference")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Select
|
||||
.get(".parameters-col_description > select")
|
||||
.select(["dog", "cat"])
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "findByPreference")
|
||||
.should("contain.text", "dog")
|
||||
.should("contain.text", "cat")
|
||||
})
|
||||
})
|
||||
describe("/petOwner/createWithList", () => {
|
||||
it("should allow execution of operation with default text in textArea in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-petOwnerCreateWithList")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "createWithList")
|
||||
})
|
||||
it("should allow execution of operation with cleared textArea in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-petOwnerCreateWithList")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".body-param__text")
|
||||
.clear()
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "createWithList")
|
||||
})
|
||||
it("should allow execution of operation with modified textArea in Try-It-Out", () => {
|
||||
cy.visit("/?url=/documents/features/schema-form-core.yaml")
|
||||
.get("#operations-petOwner-petOwnerCreateWithList")
|
||||
.click()
|
||||
// Expand Try It Out
|
||||
.get(".try-out__btn")
|
||||
.click()
|
||||
.get(".body-param__text")
|
||||
.clear()
|
||||
// note: adding this much type adds 6+ seconds to test
|
||||
.type(
|
||||
`[
|
||||
{
|
||||
"id": 10,
|
||||
"petId": 201,
|
||||
"petOwnerFirstName": "John",
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"petId": 201,
|
||||
"petOwnerFirstName": "Jane",
|
||||
}
|
||||
]`
|
||||
)
|
||||
.should("contain.text", "Jane")
|
||||
.should("contain.text", "201")
|
||||
// Execute
|
||||
.get(".execute.opblock-control__btn")
|
||||
.click()
|
||||
// Expect new element to be visible after Execute
|
||||
.get(".btn-clear.opblock-control__btn")
|
||||
.should("have.text", "Clear")
|
||||
// Compare Request URL
|
||||
.get(".request-url pre.microlight")
|
||||
.should("contain.text", "createWithList")
|
||||
// Compare Curl
|
||||
.get(".curl")
|
||||
.should("contain.text", "Jane")
|
||||
.should("contain.text", "201")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
describe("Parse YAML as YAML@1.2 with json_schema for all JSON-supported types", () => {
|
||||
it("should have date string even without quotes", () => {
|
||||
cy.visit("/?url=/documents/features/spec-parse-to-json.yaml")
|
||||
.get("#operations-default-get_foo")
|
||||
.click()
|
||||
// Responses -> example value tab
|
||||
.get(".language-json > :nth-child(3)")
|
||||
.should("have.text", "\"without-quotes\"")
|
||||
.get(".language-json > :nth-child(5)")
|
||||
.should("have.text", "\"1999-11-31\"")
|
||||
// Responses -> schema tab
|
||||
.get(".model-example > .tab > :nth-child(2)")
|
||||
.click()
|
||||
.get(":nth-child(1) > :nth-child(2) > .model > :nth-child(1)")
|
||||
.click()
|
||||
.get(
|
||||
":nth-child(1) > :nth-child(2) > .model > :nth-child(1) > .prop > .property"
|
||||
) // first element, without-quotes
|
||||
.should("have.text", "example: 1999-11-31")
|
||||
.get(":nth-child(2) > :nth-child(2) > .model > :nth-child(1)")
|
||||
.click()
|
||||
.get(
|
||||
":nth-child(2) > :nth-child(2) > .model > :nth-child(1) > .prop > .property"
|
||||
) // second element, with quotes
|
||||
.should("have.text", "example: 1999-12-31")
|
||||
})
|
||||
})
|
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @prettier
|
||||
*/
|
||||
describe("Syntax Highlighting for JSON value cases", () => {
|
||||
// expect span contains entire string sample
|
||||
// fail case is if the string sample gets broken up into segments
|
||||
// due react-syntax-highlighter attempting to escape characters into multiple segments
|
||||
describe("OAS 2", () => {
|
||||
it("should render full syntax highlighted string in Request (param body) example", () => {
|
||||
cy.visit("/?url=/documents/features/syntax-highlighting-json-oas2.yaml")
|
||||
.get("#operations-default-post_setServices")
|
||||
.click()
|
||||
.get(".body-param__example > .language-json > :nth-child(10)")
|
||||
.should("have.text", "\"79daf5b4-aa4b-1452-eae5-42c231477ba7\"")
|
||||
})
|
||||
it("should render full syntax highlighted string in Response example", () => {
|
||||
cy.visit("/?url=/documents/features/syntax-highlighting-json-oas2.yaml")
|
||||
.get("#operations-default-post_setServices")
|
||||
.click()
|
||||
.get(".example > .language-json > :nth-child(28)")
|
||||
.should("have.text", "\"5ff06f632bb165394501b05d3a833355\"")
|
||||
})
|
||||
})
|
||||
describe("OAS 3", () => {
|
||||
it("should render full syntax highlighted string in Request example", () => {
|
||||
cy.visit("/?url=/documents/features/syntax-highlighting-json-oas3.yaml")
|
||||
.get("#operations-default-post_setServices")
|
||||
.click()
|
||||
.get(".body-param__example > .language-json > :nth-child(15)")
|
||||
.should("have.text", "\"22a124b4-594b-4452-bdf5-fc3ef1477ba7\"")
|
||||
})
|
||||
it("should render full syntax highlighted string in Response example", () => {
|
||||
cy.visit("/?url=/documents/features/syntax-highlighting-json-oas3.yaml")
|
||||
.get("#operations-default-post_setServices")
|
||||
.click()
|
||||
.get(".example > .language-json > :nth-child(33)")
|
||||
.should("have.text", "\"f0009babde9dbe204540d79cf754408e\"")
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,22 @@
|
||||
describe("Try it out enabled configuration", () => {
|
||||
it("should enable the try it out section when true", () => {
|
||||
|
||||
cy
|
||||
.visit("?tryItOutEnabled=true&url=/documents/features/try-it-out-enabled.yaml")
|
||||
.get("#operations-default-get_")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.should("have.text","Cancel")
|
||||
})
|
||||
|
||||
it("should disable the try it out section when false", () => {
|
||||
|
||||
cy
|
||||
.visit("?tryItOutEnabled=false&url=/documents/features/try-it-out-enabled.yaml")
|
||||
.get("#operations-default-get_")
|
||||
.click()
|
||||
.get(".try-out__btn")
|
||||
.should("have.text","Try it out ")
|
||||
})
|
||||
})
|
||||
|
@ -0,0 +1,15 @@
|
||||
describe("Try It Out: schema required properties can be overridden", () => {
|
||||
it("should execute", () => {
|
||||
cy
|
||||
.visit("?tryItOutEnabled=true&url=/documents/features/try-it-out-schema-required-override-allowed.yaml")
|
||||
.get("#operations-default-setDeliveryLocation")
|
||||
.click()
|
||||
.get(".body-param__text")
|
||||
.should("include.value", "testProperty")
|
||||
.clear() // swagger-ui will auto insert "{}" into textarea
|
||||
.get(".execute-wrapper > .btn")
|
||||
.click()
|
||||
.get(".curl-command")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
111
frontend/web/api-doc/test/e2e-cypress/tests/features/urls.js
Normal file
111
frontend/web/api-doc/test/e2e-cypress/tests/features/urls.js
Normal file
@ -0,0 +1,111 @@
|
||||
describe("configuration options: `urls` and `urls.primaryName`", () => {
|
||||
describe("`urls` only", () => {
|
||||
it("should render a list of URLs correctly", () => {
|
||||
cy.visit("/?configUrl=/configs/urls.yaml")
|
||||
.get("select")
|
||||
.children()
|
||||
.should("have.length", 2)
|
||||
.get("select > option")
|
||||
.eq(0)
|
||||
.should("have.text", "One")
|
||||
.should("have.attr", "value", "/documents/features/urls/1.yaml")
|
||||
.get("select > option")
|
||||
.eq(1)
|
||||
.should("have.text", "Two")
|
||||
.should("have.attr", "value", "/documents/features/urls/2.yaml")
|
||||
})
|
||||
|
||||
it("should render the first URL in the list", () => {
|
||||
cy.visit("/?configUrl=/configs/urls.yaml")
|
||||
.get("h2.title")
|
||||
.should("have.text", "One")
|
||||
.window()
|
||||
.then(win => win.ui.specSelectors.url())
|
||||
.should("equal", "/documents/features/urls/1.yaml")
|
||||
})
|
||||
})
|
||||
|
||||
it("should respect a `urls.primaryName`", () => {
|
||||
cy.visit("/?configUrl=/configs/urls-primary-name.yaml")
|
||||
.get("select")
|
||||
.should("have.value", "/documents/features/urls/2.yaml")
|
||||
.get("h2.title")
|
||||
.should("have.text", "Two")
|
||||
.window()
|
||||
.then(win => win.ui.specSelectors.url())
|
||||
.should("equal", "/documents/features/urls/2.yaml")
|
||||
})
|
||||
})
|
||||
|
||||
describe("urls with server variables", () => {
|
||||
it("should compute a url and default server variables", () => {
|
||||
cy.visit("/?configUrl=/configs/urls-server-variables.yaml")
|
||||
.get("code")
|
||||
.should("have.text", "https://localhost:3200/oneFirstUrl")
|
||||
.get("tr > :nth-child(1)")
|
||||
.should("have.text", "basePath")
|
||||
.get("input")
|
||||
.should("have.value", "/oneFirstUrl")
|
||||
})
|
||||
it("should change server variables", () => {
|
||||
cy.visit("/?configUrl=/configs/urls-server-variables.yaml")
|
||||
.get("code")
|
||||
.should("have.text", "https://localhost:3200/oneFirstUrl")
|
||||
.get("tr > :nth-child(1)")
|
||||
.should("have.text", "basePath")
|
||||
.get("input")
|
||||
.should("have.value", "/oneFirstUrl")
|
||||
.get(".servers > label > select")
|
||||
.eq(0)
|
||||
.select(1)
|
||||
.get("input")
|
||||
.should("have.value", "/oneSecondUrl")
|
||||
})
|
||||
it("should select and compute second url", () => {
|
||||
cy.visit("/?configUrl=/configs/urls-server-variables.yaml")
|
||||
.get("select > option")
|
||||
.eq(1)
|
||||
.should("have.text", "Two")
|
||||
.get("select")
|
||||
.eq(0)
|
||||
.select(1)
|
||||
.get("code")
|
||||
.should("have.text", "https://localhost:3200/twoFirstUrl")
|
||||
.get("input")
|
||||
.should("have.value", "/twoFirstUrl")
|
||||
})
|
||||
it("should select second url, then toggle back to first url", () => {
|
||||
cy.visit("/?configUrl=/configs/urls-server-variables.yaml")
|
||||
.get("select > option")
|
||||
.get("select")
|
||||
.eq(0)
|
||||
.select(1)
|
||||
.get("input")
|
||||
.should("have.value", "/twoFirstUrl")
|
||||
// toggle url back
|
||||
.get("select")
|
||||
.eq(0)
|
||||
.select(0)
|
||||
.get("code")
|
||||
.should("have.text", "https://localhost:3200/oneFirstUrl")
|
||||
.get("input")
|
||||
.should("have.value", "/oneFirstUrl")
|
||||
})
|
||||
it("should change server variables, then select second url, and maintain server variables index", () => {
|
||||
cy.visit("/?configUrl=/configs/urls-server-variables.yaml")
|
||||
.get(".servers > label >select")
|
||||
.eq(0)
|
||||
.select(1)
|
||||
.get("input")
|
||||
.should("have.value", "/oneSecondUrl")
|
||||
// change url
|
||||
.get("select > option")
|
||||
.get("select")
|
||||
.eq(0)
|
||||
.select(1)
|
||||
.get("input")
|
||||
.should("have.value", "/twoSecondUrl")
|
||||
.get("input")
|
||||
.should("have.value", "/twoSecondUrl")
|
||||
})
|
||||
})
|
@ -0,0 +1,22 @@
|
||||
describe("#6767: Operation should be considered anonymous if its security only includes empty object (this was decided by implementation choice and may change or be extended in the future)", () => {
|
||||
it("Should consider method anonymous if security contains only empty object", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/security/anonymous.yaml")
|
||||
.get("#operations-default-get_onlyEmpty .authorization__btn")
|
||||
.should("not.exist")
|
||||
})
|
||||
|
||||
it("Should consider method as secured if security contains no empty object", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/security/anonymous.yaml")
|
||||
.get("#operations-default-get_required .authorization__btn")
|
||||
.should("exist")
|
||||
})
|
||||
|
||||
it("Should consider method as secured if security contains empty object but has at least one more security defined", () => {
|
||||
cy
|
||||
.visit("/?url=/documents/security/anonymous.yaml")
|
||||
.get("#operations-default-get_withBoth .authorization__btn")
|
||||
.should("exist")
|
||||
})
|
||||
})
|
@ -0,0 +1,23 @@
|
||||
describe("XSS: OAuth2 authorizationUrl sanitization", () => {
|
||||
it("should filter out a javascript URL", () => {
|
||||
cy.visit("/?url=/documents/security/xss-oauth2.yaml")
|
||||
.window()
|
||||
.then(win => {
|
||||
let args = null
|
||||
const stub = cy.stub(win, "open", (...callArgs) => {
|
||||
args = callArgs
|
||||
}).as("windowOpen")
|
||||
|
||||
cy.get(".authorize")
|
||||
.click()
|
||||
.get(".modal-btn.authorize")
|
||||
.click()
|
||||
.wait(100)
|
||||
.then(() => {
|
||||
console.log(args)
|
||||
expect(args[0]).to.match(/^about:blank/)
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,58 @@
|
||||
describe("Security: CSS Sequential Import Chaining", () => {
|
||||
describe("in OpenAPI 3.0", () => {
|
||||
describe("CSS Injection via Markdown", () => {
|
||||
it("should filter <style> tags out of Markdown fields", () => {
|
||||
cy.visit("/?url=/documents/security/sequential-import-chaining/openapi.yaml")
|
||||
.get("div.information-container")
|
||||
.should("exist")
|
||||
.and("not.have.descendants", "style")
|
||||
})
|
||||
it("should not apply `@import`ed CSS stylesheets", () => {
|
||||
cy.visit("/?url=/documents/security/sequential-import-chaining/openapi.yaml")
|
||||
.wait(500) // HACK: wait for CSS import to settle
|
||||
.get("div.info h4")
|
||||
.should("have.length", 1)
|
||||
.and("not.be.hidden")
|
||||
})
|
||||
})
|
||||
describe("Value Exfiltration via CSS", () => {
|
||||
it("should not allow OAuth credentials to be visible via HTML `value` attribute", () => {
|
||||
cy.visit("/?url=/documents/petstore-expanded.openapi.yaml")
|
||||
.get(".scheme-container > .schemes > .auth-wrapper > .btn > span")
|
||||
.click()
|
||||
.get("div > div > .wrapper > .block-tablet > #client_id")
|
||||
.clear()
|
||||
.type("abc")
|
||||
.should("not.have.attr", "value", "abc")
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("in Swagger 2.0", () => {
|
||||
describe("CSS Injection via Markdown", () => {
|
||||
it("should filter <style> tags out of Markdown fields", () => {
|
||||
cy.visit("/?url=/documents/security/sequential-import-chaining/swagger.yaml")
|
||||
.get("div.information-container")
|
||||
.should("exist")
|
||||
.and("not.have.descendants", "style")
|
||||
})
|
||||
it("should not apply `@import`ed CSS stylesheets", () => {
|
||||
cy.visit("/?url=/documents/security/sequential-import-chaining/swagger.yaml")
|
||||
.wait(500) // HACK: wait for CSS import to settle
|
||||
.get("div.info h4")
|
||||
.should("have.length", 1)
|
||||
.and("not.be.hidden")
|
||||
})
|
||||
})
|
||||
describe("Value Exfiltration via CSS", () => {
|
||||
it("should not allow OAuth credentials to be visible via HTML `value` attribute", () => {
|
||||
cy.visit("/?url=/documents/petstore.swagger.yaml")
|
||||
.get(".scheme-container > .schemes > .auth-wrapper > .btn > span")
|
||||
.click()
|
||||
.get("div > div > .wrapper > .block-tablet > #client_id")
|
||||
.clear()
|
||||
.type("abc")
|
||||
.should("not.have.attr", "value", "abc")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user