diff --git a/.github/issue_template.md b/.github/issue_template.md
index 1b519695..77c30a7e 100644
--- a/.github/issue_template.md
+++ b/.github/issue_template.md
@@ -1,3 +1,63 @@
-When reporting an issue, please provide the following details:
-- swagger-ui version
-- a swagger file reproducing the issue
+
+
+
+
+
+| Q | A
+| ------------------------------- | -------
+| Bug or feature request? |
+| Which Swagger/OpenAPI version? |
+| Which Swagger-UI version? |
+| How did you install Swagger-UI? |
+| Which broswer & version? |
+| Which operating system? |
+
+
+### Demonstration API definition
+
+
+
+
+
+```yaml
+your: "API definition goes here"
+```
+
+### Configuration (browser query string, constructor, config.yaml)
+
+
+```js
+{
+ "your": { "constructorConfig": "here" }
+}
+```
+
+`?yourQueryStringConfig=here`
+
+### Expected Behavior
+
+
+
+### Current Behavior
+
+
+
+### Possible Solution
+
+
+
+### Context
+
+
diff --git a/.gitignore b/.gitignore
index 2e9dcf9c..8c713860 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ npm-debug.log*
.eslintcache
package-lock.json
*.iml
+selenium-debug.log
+test/e2e/db.json
diff --git a/README.md b/README.md
index 15e5429a..57b1aaf8 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,15 @@ If you'd like to make modifications to the codebase, run the dev server with: `n
If you'd like to rebuild the `/dist` folder with your codebase changes, run `npm run build`.
+
+##### Integration Tests
+
+You will need JDK of version 7 or higher as instructed here
+http://nightwatchjs.org/gettingstarted#selenium-server-setup
+
+Integration tests can be run locally with `npm run e2e` - be sure you aren't running a dev server when testing!
+
+
##### Browser support
Swagger UI works in the latest versions of Chrome, Safari, Firefox, Edge and IE11.
diff --git a/make-webpack-config.js b/make-webpack-config.js
index 2eeb9bf9..c2cc2268 100644
--- a/make-webpack-config.js
+++ b/make-webpack-config.js
@@ -1,9 +1,10 @@
var path = require("path")
-var webpack = require("webpack")
-var ExtractTextPlugin = require("extract-text-webpack-plugin")
-var deepExtend = require("deep-extend")
-const {gitDescribeSync} = require("git-describe")
+var webpack = require('webpack')
+var ExtractTextPlugin = require('extract-text-webpack-plugin')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+var deepExtend = require('deep-extend')
+const {gitDescribeSync} = require('git-describe')
const os = require("os")
var pkg = require("./package.json")
@@ -60,7 +61,8 @@ module.exports = function(rules, options) {
}))
}
- if( specialOptions.minimize ) {
+ if( specialOptions.minimize ) { // production mode
+
plugins.push(
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
@@ -74,6 +76,8 @@ module.exports = function(rules, options) {
plugins.push( new webpack.NoEmitOnErrorsPlugin())
+ } else { // development mode
+ plugins.push(new CopyWebpackPlugin([ { from: 'test/e2e/specs', to: 'test-specs' } ]))
}
plugins.push(
diff --git a/package.json b/package.json
index 062afa03..1a2ce9d1 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,11 @@
"test": "npm run lint-errors && npm run just-test-in-node",
"test-in-node": "npm run lint-errors && npm run just-test-in-node",
"just-test": "karma start --config karma.conf.js",
- "just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components test/bugs test/swagger-ui-dist-package"
+ "just-test-in-node": "mocha --recursive --compilers js:babel-core/register test/core test/components test/bugs test/swagger-ui-dist-package",
+ "test-e2e": "sleep 3 && nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json",
+ "e2e-initial-render": "nightwatch test/e2e/scenarios/ --config test/e2e/nightwatch.json --group initial-render",
+ "mock-api": "json-server --watch test/e2e/db.json --port 3204",
+ "e2e": "npm-run-all --parallel -r hot-server mock-api test-e2e"
},
"dependencies": {
"base64-js": "^1.2.0",
@@ -90,6 +94,8 @@
"babel-preset-react": "^6.23.0",
"babel-preset-stage-0": "^6.22.0",
"babel-runtime": "^6.23.0",
+ "chromedriver": "^2.30.1",
+ "copy-webpack-plugin": "^4.0.1",
"css-loader": "0.28.4",
"deep-extend": "^0.5.0",
"deepmerge": "^1.3.2",
@@ -100,9 +106,9 @@
"extract-text-webpack-plugin": "^2.1.2",
"file-loader": "0.11.2",
"git-describe": "^4.0.1",
- "html-webpack-plugin": "^2.28.0",
"imports-loader": "0.7.1",
"json-loader": "0.5.4",
+ "json-server": "^0.11.0",
"karma": "^1.7.0",
"karma-chrome-launcher": "^2.2.0",
"karma-mocha": "^1.3.0",
@@ -111,6 +117,7 @@
"less": "2.7.2",
"license-checker": "^11.0.0",
"mocha": "^3.4.2",
+ "nightwatch": "^0.9.16",
"node-sass": "^4.5.0",
"npm-run-all": "4.0.2",
"null-loader": "0.1.1",
@@ -121,6 +128,7 @@
"react-test-renderer": "^15.5.4",
"rimraf": "^2.6.0",
"sass-loader": "^6.0.2",
+ "selenium-server-standalone-jar": "3.4.0",
"standard": "^10.0.2",
"standard-loader": "^6.0.1",
"style-loader": "0.18.2",
diff --git a/src/core/components/layouts/base.jsx b/src/core/components/layouts/base.jsx
index f502b88f..268ef46c 100644
--- a/src/core/components/layouts/base.jsx
+++ b/src/core/components/layouts/base.jsx
@@ -69,7 +69,10 @@ export default class BaseLayout extends React.Component {
{ schemes && schemes.size ? (
-
+
) : null }
{ securityDefinitions ? (
diff --git a/src/core/components/operation.jsx b/src/core/components/operation.jsx
index fc182a1e..4f6534db 100644
--- a/src/core/components/operation.jsx
+++ b/src/core/components/operation.jsx
@@ -229,7 +229,7 @@ export default class Operation extends PureComponent {
path={ path }
method={ method }
specActions={ specActions }
- operationScheme={ operationScheme } />
+ currentScheme={ operationScheme } />
: null
}
diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx
index 95602c64..9d30849d 100644
--- a/src/core/components/response.jsx
+++ b/src/core/components/response.jsx
@@ -122,10 +122,10 @@ export default class Response extends React.Component {
- {specSelectors.isOAS3() ?
+ {specSelectors.isOAS3() ? |
{ links ?
links.toSeq().map((link, key) => {
- return
+ return
})
: No links}
| : null}
diff --git a/src/core/components/responses.jsx b/src/core/components/responses.jsx
index 1c00ff1a..88ab0c92 100644
--- a/src/core/components/responses.jsx
+++ b/src/core/components/responses.jsx
@@ -68,7 +68,7 @@ export default class Responses extends React.Component {
| Code |
Description |
- { specSelectors.isOAS3() ? Links | : null }
+ { specSelectors.isOAS3() ? Links | : null }
diff --git a/src/core/components/schemes.jsx b/src/core/components/schemes.jsx
index f9fe8f81..ed0947fe 100644
--- a/src/core/components/schemes.jsx
+++ b/src/core/components/schemes.jsx
@@ -6,9 +6,9 @@ export default class Schemes extends React.Component {
static propTypes = {
specActions: PropTypes.object.isRequired,
schemes: PropTypes.object.isRequired,
+ currentScheme: PropTypes.string.isRequired,
path: PropTypes.string,
method: PropTypes.string,
- operationScheme: PropTypes.string
}
componentWillMount() {
@@ -19,8 +19,8 @@ export default class Schemes extends React.Component {
}
componentWillReceiveProps(nextProps) {
- if ( !this.props.operationScheme || !nextProps.schemes.has(this.props.operationScheme) ) {
- // if we don't have a selected operationScheme or if our selected scheme is no longer an option,
+ if ( !this.props.currentScheme || !nextProps.schemes.includes(this.props.currentScheme) ) {
+ // if we don't have a selected currentScheme or if our selected scheme is no longer an option,
// then fire 'change' event and select the first scheme in the list of options
this.setScheme(nextProps.schemes.first())
}
diff --git a/src/core/plugins/oas3/components/operation-link.jsx b/src/core/plugins/oas3/components/operation-link.jsx
index 6f9eef0a..4e9aba91 100644
--- a/src/core/plugins/oas3/components/operation-link.jsx
+++ b/src/core/plugins/oas3/components/operation-link.jsx
@@ -4,19 +4,24 @@ import ImPropTypes from "react-immutable-proptypes"
class OperationLink extends Component {
render() {
- const { link, name } = this.props
+ const { link, name, getComponent } = this.props
+
+ const Markdown = getComponent("Markdown")
let targetOp = link.get("operationId") || link.get("operationRef")
let parameters = link.get("parameters") && link.get("parameters").toJS()
let description = link.get("description")
- return
- {name}{description ? `: ${description}` : ""}
+ return
+
+ {name}
+ { description ? : null }
+
Operation `{targetOp}`
Parameters {padString(0, JSON.stringify(parameters, null, 2)) || "{}"}
-
+
}
}
@@ -30,6 +35,7 @@ function padString(n, string) {
}
OperationLink.propTypes = {
+ getComponent: PropTypes.func.isRequired,
link: ImPropTypes.orderedMap.isRequired,
name: PropTypes.String
}
diff --git a/src/style/_layout.scss b/src/style/_layout.scss
index b99064d1..9ee357f0 100644
--- a/src/style/_layout.scss
+++ b/src/style/_layout.scss
@@ -522,6 +522,22 @@
}
}
+.response-col_links
+{
+ padding-left: 2em;
+ max-width: 40em;
+ font-size: 14px;
+
+ @include text_body();
+
+ .response-undocumented
+ {
+ font-size: 11px;
+
+ @include text_code(#999);
+ }
+}
+
.response-col_description__inner
{
span
diff --git a/src/style/_table.scss b/src/style/_table.scss
index cfec861a..7f065529 100644
--- a/src/style/_table.scss
+++ b/src/style/_table.scss
@@ -52,7 +52,8 @@ table
&:first-of-type
{
- width: 20%;
+ max-width: 20%;
+ min-width: 6em;
padding: 10px 0;
}
}
diff --git a/test/components/schemes.js b/test/components/schemes.js
index a21c0628..f8f5730c 100644
--- a/test/components/schemes.js
+++ b/test/components/schemes.js
@@ -7,35 +7,66 @@ import { fromJS } from "immutable"
import Schemes from "components/schemes"
describe("", function(){
- it("calls props.specActions.setScheme() when no operationScheme is selected", function(){
+ it("calls props.specActions.setScheme() when no currentScheme is selected", function(){
+
+ let setSchemeSpy = createSpy()
// Given
let props = {
specActions: {
- setScheme: createSpy()
+ setScheme: setSchemeSpy
},
schemes: fromJS([
"http",
"https"
]),
- operationScheme: undefined,
+ currentScheme: undefined,
path: "/test",
method: "get"
}
-
+
// When
let wrapper = shallow()
- // Then operationScheme should default to first scheme in options list
+ // Then currentScheme should default to first scheme in options list
expect(props.specActions.setScheme).toHaveBeenCalledWith("http", "/test" , "get")
- // When the operationScheme is no longer in the list of options
+ // When the currentScheme is no longer in the list of options
props.schemes = fromJS([
"https"
])
wrapper.setProps(props)
- // Then operationScheme should default to first scheme in options list
+ // Then currentScheme should default to first scheme in options list, again
expect(props.specActions.setScheme).toHaveBeenCalledWith("https", "/test", "get")
})
+
+ it("doesn't call props.specActions.setScheme() when schemes hasn't changed", function(){
+
+ let setSchemeSpy = createSpy()
+
+ // Given
+ let props = {
+ specActions: {
+ setScheme: setSchemeSpy
+ },
+ schemes: fromJS([
+ "http",
+ "https"
+ ]),
+ currentScheme: "https"
+ }
+
+ // When
+ let wrapper = shallow()
+
+ // Should be called initially, to set the global state
+ expect(setSchemeSpy.calls.length).toEqual(1)
+
+ // After an update
+ wrapper.instance().componentWillReceiveProps(props)
+
+ // Should not be called again, since `currentScheme` is in schemes
+ expect(setSchemeSpy.calls.length).toEqual(1)
+ })
})
diff --git a/test/e2e/db.json b/test/e2e/db.json
new file mode 100644
index 00000000..e33ceaad
--- /dev/null
+++ b/test/e2e/db.json
@@ -0,0 +1,130 @@
+{
+ "pet": [
+ {
+ "id": 1,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ },
+ {
+ "id": 2,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ },
+ {
+ "id": 3,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ },
+ {
+ "id": 4,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ },
+ {
+ "id": 5,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ },
+ {
+ "id": 6,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ },
+ {
+ "id": 7,
+ "category": {
+ "id": 0,
+ "name": "string"
+ },
+ "name": "doggie",
+ "photoUrls": [
+ "string"
+ ],
+ "tags": [
+ {
+ "id": 0,
+ "name": "string"
+ }
+ ],
+ "status": "available"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/e2e/nightwatch.json b/test/e2e/nightwatch.json
new file mode 100644
index 00000000..16ac8bcc
--- /dev/null
+++ b/test/e2e/nightwatch.json
@@ -0,0 +1,63 @@
+{
+ "src_folders" : ["test/e2e/scenarios"],
+ "output_folder" : "reports",
+ "live_output": true,
+ "custom_commands_path" : "",
+ "custom_assertions_path" : "",
+ "page_objects_path" : "test/e2e/pages",
+ "globals_path" : "",
+ "test_workers" : {
+ "enabled" : true,
+ "workers" : "auto"
+ },
+
+ "test_runner" : {
+ "type" : "mocha",
+ "options" : {
+ "ui" : "bdd",
+ "reporter" : "list"
+ }
+ },
+
+ "selenium" : {
+ "start_process" : true,
+ "server_path" : "node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-3.4.0.jar",
+ "log_path" : "",
+ "host" : "127.0.0.1",
+ "port" : 4444,
+ "cli_args" : {
+ "webdriver.chrome.driver" : "node_modules/chromedriver/bin/chromedriver",
+ "webdriver.firefox.profile" : "",
+ "webdriver.ie.driver" : ""
+ }
+ },
+
+ "test_settings" : {
+ "default" : {
+ "launch_url" : "http://localhost",
+ "selenium_port" : 4444,
+ "selenium_host" : "localhost",
+ "silent": true,
+ "screenshots" : {
+ "enabled" : false,
+ "path" : ""
+ },
+ "desiredCapabilities": {
+ "browserName": "chrome",
+ "marionette": true
+ }
+ },
+
+ "chrome" : {
+ "desiredCapabilities": {
+ "browserName": "chrome"
+ }
+ },
+
+ "edge" : {
+ "desiredCapabilities": {
+ "browserName": "MicrosoftEdge"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/e2e/pages/main.js b/test/e2e/pages/main.js
new file mode 100644
index 00000000..c3bbb558
--- /dev/null
+++ b/test/e2e/pages/main.js
@@ -0,0 +1,505 @@
+module.exports = {
+ sections: {
+ topbar: {
+ selector: ".topbar",
+ elements: {
+ inputBox: {
+ selector: "input"
+ },
+ btnExplore: {
+ selector: "button"
+ }
+ }
+ },
+ informationContainer: {
+ selector: ".information-container.wrapper",
+ elements: {
+ title: {
+ selector: ".title"
+ },
+ version: {
+ selector: ".version"
+ },
+ baseUrl: {
+ selector: ".base-url"
+ },
+ mainUrl: {
+ selector: ".main a"
+ },
+ mainUrlContent: {
+ selector: ".main a span"
+ },
+ description: {
+ selector: ".description p"
+ },
+ swaggerUrl: {
+ selector: ".description p a:nth-of-type(1)"
+ },
+ swaggerircUrl: {
+ selector: ".description p a:nth-of-type(2)"
+ },
+ termsLink: {
+ selector: ".info > div:nth-child(3) a"
+ },
+ contactDevLink: {
+ selector: ".info > div:nth-child(4) a"
+ },
+ apacheLink: {
+ selector: ".info > div:nth-child(5) a"
+ },
+ aboutSwaggerLink: {
+ selector: ".info > a"
+ }
+ }
+ },
+ schemeContainer: {
+ selector: ".scheme-container",
+ elements: {
+ httpOption: {
+ selector: "select option"
+ },
+ btnAuthorize: {
+ selector: "button.authorize"
+ },
+ authorizationModal: {
+ selector: ".dialog-ux"
+ },
+ appName: {
+ selector: ".auth-container h5"
+ },
+ authorizationUrl: {
+ selector: ".auth-container code"
+ },
+ flow: {
+ selector: ".flow code"
+ },
+ inputClientID: {
+ selector: "#client_id"
+ },
+ checkWritePetStoreAuth: {
+ selector: "#write:pets-checkbox-petstore_auth"
+ },
+ checkReadPetStoreAuth: {
+ selector: "#read:pets-checkbox-petstore_auth"
+ }
+ }
+ },
+ apiWrapper: {
+ selector: ".swagger-ui .wrapper:nth-child(3)",
+ elements: {
+ petAPIWrapper: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1)"
+ },
+ petAPIWrapperBar: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) .opblock-tag"
+ },
+ /**
+ * Post pet/ api
+ */
+ petOperationPostContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet"
+ },
+ petOperationPostTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet .opblock-summary-post span.opblock-summary-path span"
+ },
+ petOperationPostCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet .opblock-summary-post"
+ },
+ petOperationPostCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet>div:nth-child(2)"
+ },
+ petOperationPostTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet button.try-out__btn"
+ },
+ petOperationPostTryText: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet textarea.body-param__text"
+ },
+ petOperationPostExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet button.execute"
+ },
+ petOperationPostTryTextArea: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet textarea"
+ },
+ petOperationPostResultsBox: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight"
+ },
+ petOperationPostMockCategoryID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(17)"
+ },
+ petOperationPostMockCategoryName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(23)"
+ },
+ petOperationPostMockName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(31)"
+ },
+ petOperationPostTagID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(54)"
+ },
+ petOperationPostTagName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(60)"
+ },
+ petOperationPostStatus: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-addPet pre.microlight span:nth-child(70)"
+ },
+ /**
+ * Put pet/ api
+ */
+ petOperationPutContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet"
+ },
+ petOperationPutTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet .opblock-summary-put span.opblock-summary-path span"
+ },
+ petOperationPutCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet .opblock-summary-put"
+ },
+ petOperationPutCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet>div:nth-child(2)"
+ },
+ petOperationPutTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet button.try-out__btn"
+ },
+ petOperationPutTryText: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet textarea.body-param__text"
+ },
+ petOperationPutExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet button.execute"
+ },
+ petOperationPutTryTextArea: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet textarea"
+ },
+ petOperationPutResultsBox: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight"
+ },
+ petOperationPutMockCategoryID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(17)"
+ },
+ petOperationPutMockCategoryName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(23)"
+ },
+ petOperationPutMockName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(31)"
+ },
+ petOperationPutTagID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(54)"
+ },
+ petOperationPutTagName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(60)"
+ },
+ petOperationPutStatus: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-updatePet pre.microlight span:nth-child(70)"
+ },
+ /**
+ * Get pet/
+ */
+ petOperationGetByTagContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags"
+ },
+ petOperationGetByTagTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags .opblock-summary-get span.opblock-summary-path__deprecated span"
+ },
+ petOperationGetByTagCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags .opblock-summary-get"
+ },
+ petOperationGetByTagCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags .ReactCollapse--collapse"
+ },
+ petOperationGetByTagTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags button.try-out__btn"
+ },
+ petOperationGetByTagTryAdded: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags button.json-schema-form-item-add"
+ },
+ petOperationGetByTagExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags button.execute"
+ },
+ petOperationGetByTagTryTextArea: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags textarea"
+ },
+ petOperationGetByTagResultsBox: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight"
+ },
+ petOperationGetByTagMockCategoryID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(17)"
+ },
+ petOperationGetByTagMockCategoryName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(23)"
+ },
+ petOperationGetByTagMockName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(31)"
+ },
+ petOperationGetByTagTagID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(54)"
+ },
+ petOperationGetByTagTagName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(60)"
+ },
+ petOperationGetByTagStatus: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-findPetsByTags pre.microlight span:nth-child(70)"
+ },
+
+ /**
+ * Delete pet/
+ */
+ petOperationDeleteContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet"
+ },
+ petOperationDeleteTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet .opblock-summary-delete span.opblock-summary-path span"
+ },
+ petOperationDeleteCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet .opblock-summary-delete"
+ },
+ petOperationDeleteCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet>div:nth-child(2)"
+ },
+ petOperationDeleteTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet button.try-out__btn"
+ },
+ petOperationDeleteExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet button.execute"
+ },
+ petOperationDeleteTryTextArea: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet textarea"
+ },
+ petOperationDeleteResultsBox: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight"
+ },
+ petOperationDeleteMockCategoryID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight span:nth-child(17)"
+ },
+ petOperationDeleteMockCategoryName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight span:nth-child(23)"
+ },
+ petOperationDeleteMockName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight span:nth-child(31)"
+ },
+ petOperationDeleteTagID: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight span:nth-child(54)"
+ },
+ petOperationDeleteTagName: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight span:nth-child(60)"
+ },
+ petOperationDeleteStatus: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(1) div#operations-pet-deletePet pre.microlight span:nth-child(70)"
+ },
+
+ /**
+ * ***********Store************
+ */
+ storeAPIWrapper: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2)"
+ },
+ storeAPIWrapperBar: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) .opblock-tag"
+ },
+ /**
+ * Get /store/inventory
+ */
+ storeOperationGetContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory"
+ },
+ storeOperationGetTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory .opblock-summary-get span.opblock-summary-path span"
+ },
+ storeOperationGetCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory .opblock-summary-get"
+ },
+ storeOperationGetCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory>div:nth-child(2)"
+ },
+ storeOperationGetTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory button.try-out__btn"
+ },
+ storeOperationGetExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory button.execute"
+ },
+ storeOperationResponseProps1: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory pre.example.microlight span:nth-child(6)"
+ },
+ storeOperationResponseProps2: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory pre.example.microlight span:nth-child(12)"
+ },
+ storeOperationResponseProps3: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-getInventory pre.example.microlight span:nth-child(18)"
+ },
+ /**
+ * Post /store/order
+ */
+ storeOperationPostContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder"
+ },
+ storeOperationPostTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder .opblock-summary-post span.opblock-summary-path span"
+ },
+ storeOperationPostCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder .opblock-summary-post"
+ },
+ storeOperationPostCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder>div:nth-child(2)"
+ },
+ storeOperationPostTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder button.try-out__btn"
+ },
+ storeOperationPostExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder button.execute"
+ },
+ storeOperationPostResponseId: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder pre.example.microlight span:nth-child(22)"
+ },
+ storeOperationPostResponsePetId: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder pre.example.microlight span:nth-child(31)"
+ },
+ storeOperationPostResponseQuantity: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder pre.example.microlight span:nth-child(40)"
+ },
+ storeOperationPostResponseStatus: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder pre.example.microlight span:nth-child(66)"
+ },
+ storeOperationPostResponseComplete: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-placeOrder pre.example.microlight span:nth-child(75)"
+ },
+ /**
+ * Delete /store/order/{orderId}
+ */
+ storeOperationDeleteContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder"
+ },
+ storeOperationDeleteTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder .opblock-summary-delete span.opblock-summary-path span"
+ },
+ storeOperationDeleteCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder .opblock-summary-delete"
+ },
+ storeOperationDeleteCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder>div:nth-child(2)"
+ },
+ storeOperationDeleteTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder button.try-out__btn"
+ },
+ storeOperationDeleteExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder button.execute"
+ },
+ storeOperationGetResponseHeaders: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(2) div#operations-store-deleteOrder pre span"
+ },
+ /**
+ * *********User**************
+ */
+ userAPIWrapper: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3)"
+ },
+ userAPIWrapperBar: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) .opblock-tag"
+ },
+ /**
+ * Put /user/login
+ */
+ userOperationPutContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser"
+ },
+ userOperationPutTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser .opblock-summary-put span.opblock-summary-path span"
+ },
+ userOperationPutCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser .opblock-summary-put"
+ },
+ userOperationPutCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser>div:nth-child(2)"
+ },
+ userOperationPutTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser button.try-out__btn"
+ },
+ userOperationPutExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser button.execute"
+ },
+ userOperationPutParameter: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser div.parameters-col_description input"
+ },
+ userOperationPutResponseHeader: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-updateUser div.parameters-col_description input"
+ },
+ /**
+ * Delete /user
+ */
+ userOperationDeleteContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser"
+ },
+ userOperationDeleteTitle: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser .opblock-summary-delete span.opblock-summary-path span"
+ },
+ userOperationDeleteCollpase: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser .opblock-summary-delete"
+ },
+ userOperationDeleteCollapseContainer: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser>div:nth-child(2)"
+ },
+ userOperationDeleteTryBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser button.try-out__btn"
+ },
+ userOperationDeleteExecuteBtn: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser button.execute"
+ },
+ userOperationDeleteParameter: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) div#operations-user-deleteUser div.parameters-col_description input"
+ },
+ userOperationDeleteResponseHeader: {
+ selector: ".swagger-ui .opblock-tag-section:nth-child(3) .opblock-delete div.parameters-col_description input"
+ },
+
+ }
+ },
+ /* Model Container */
+ modelWrapper: {
+ selector: ".swagger-ui .wrapper:nth-child(4)",
+ elements: {
+ modelContainer: {
+ selector: ".swagger-ui .models"
+ },
+ modelCollapse: {
+ selector: ".swagger-ui .models h4"
+ },
+ orderModel: {
+ selector: "section.models div.model-container:nth-child(1)"
+ },
+ orderModelCallapse: {
+ selector: "section.models div.model-container:nth-child(1) span.model-toggle"
+ },
+ categoryModel: {
+ selector: "section.models div.model-container:nth-child(2)"
+ },
+ categoryModelCallapse: {
+ selector: "section.models div.model-container:nth-child(2) span.model-toggle"
+ },
+ userModel: {
+ selector: "section.models div.model-container:nth-child(3)"
+ },
+ userModelCallapse: {
+ selector: "section.models div.model-container:nth-child(3) span.model-toggle"
+ },
+ tagModel: {
+ selector: "section.models div.model-container:nth-child(4)"
+ },
+ tagModelCallapse: {
+ selector: "section.models div.model-container:nth-child(4) span.model-toggle"
+ },
+ petModel: {
+ selector: "section.models div.model-container:nth-child(5)"
+ },
+ petModelCallapse: {
+ selector: "section.models div.model-container:nth-child(5) span.model-toggle"
+ },
+ apiResponseModel: {
+ selector: "section.models div.model-container:nth-child(6)"
+ },
+ apiResponseModelCallapse: {
+ selector: "section.models div.model-container:nth-child(6) span.model-toggle"
+ },
+ }
+ }
+
+
+
+
+ }
+}
diff --git a/test/e2e/scenarios/informationContainer.js b/test/e2e/scenarios/informationContainer.js
new file mode 100644
index 00000000..c5af4148
--- /dev/null
+++ b/test/e2e/scenarios/informationContainer.js
@@ -0,0 +1,48 @@
+describe("render informationContainer", function () {
+ let mainPage
+ let informationContainer
+ beforeEach(function (client, done) {
+
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+ client.waitForElementVisible(".download-url-input", 5000)
+ .pause(5000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+ informationContainer = mainPage.section.informationContainer
+
+ done()
+ })
+
+ it("renders section", function (client) {
+ mainPage.expect.section("@informationContainer").to.be.visible.before(5000)
+
+ client.end()
+ })
+
+ it("renders content", function (client) {
+ informationContainer.waitForElementVisible("@title", 5000)
+ .assert.containsText("@title", "Swagger Petstore")
+ .assert.containsText("@version", "1.0.0")
+ .assert.containsText("@baseUrl", "[ Base URL: localhost:3204/ ]")
+ .assert.attributeEquals("@mainUrl", "href", "http://localhost:3200/test-specs/petstore.json")
+ .assert.containsText("@mainUrlContent", "http://localhost:3200/test-specs/petstore.json")
+ .assert.containsText("@description", "This is a sample server Petstore server. You can find out more about Swagger at http://swagger.io or on irc.freenode.net, #swagger. For this sample, you can use the api key special-key to test the authorization filters.")
+ .assert.attributeEquals("@swaggerUrl", "href", "http://swagger.io/")
+ .assert.attributeEquals("@swaggerircUrl", "href", "http://swagger.io/irc/")
+ .assert.attributeEquals("@termsLink", "href", "http://swagger.io/terms/")
+ .assert.containsText("@termsLink", "Terms of service")
+ .assert.attributeEquals("@contactDevLink", "href", "mailto:apiteam@swagger.io")
+ .assert.containsText("@contactDevLink", "Contact the developer")
+ .assert.attributeEquals("@contactDevLink", "href", "mailto:apiteam@swagger.io")
+ .assert.containsText("@contactDevLink", "Contact the developer")
+ .assert.attributeEquals("@aboutSwaggerLink", "href", "http://swagger.io/")
+ .assert.containsText("@aboutSwaggerLink", "Find out more about Swagger")
+
+ client.end()
+ })
+})
\ No newline at end of file
diff --git a/test/e2e/scenarios/models.js b/test/e2e/scenarios/models.js
new file mode 100644
index 00000000..9749b811
--- /dev/null
+++ b/test/e2e/scenarios/models.js
@@ -0,0 +1,79 @@
+describe("Render Model Wrapper", function () {
+ let modelWrapper, mainPage
+
+ beforeEach(function (client, done) {
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+ client.waitForElementVisible(".download-url-input", 5000)
+ .pause(5000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+ modelWrapper = mainPage.section.modelWrapper
+
+ done()
+ })
+ afterEach(function (client, done){
+ done()
+ })
+ it("Render model wrapper", function(client){
+ mainPage.expect.section("@modelWrapper").to.be.visible.before(5000)
+
+ client.end()
+ })
+
+ it("Render model wrapper collapse", function(client){
+ modelWrapper.waitForElementVisible("@modelContainer", 5000)
+ .click("@modelCollapse")
+ .assert.cssClassNotPresent("@modelContainer", "is-open")
+
+ client.end()
+ })
+
+ it("Testing order model", function(client){
+ modelWrapper.waitForElementVisible("@orderModel")
+ .click("@orderModelCallapse")
+ .assert.cssClassNotPresent("@orderModelCallapse", "callapsed")
+
+ client.end()
+ })
+
+ it("Testing category model", function(client){
+ modelWrapper.waitForElementVisible("@categoryModel")
+ .click("@categoryModelCallapse")
+ .assert.cssClassNotPresent("@categoryModelCallapse", "callapsed")
+
+ client.end()
+ })
+ it("Testing user model", function(client){
+ modelWrapper.waitForElementVisible("@userModel")
+ .click("@userModelCallapse")
+ .assert.cssClassNotPresent("@userModelCallapse", "callapsed")
+
+ client.end()
+ })
+ it("Testing tag model", function(client){
+ modelWrapper.waitForElementVisible("@tagModel")
+ .click("@tagModelCallapse")
+ .assert.cssClassNotPresent("@tagModelCallapse", "callapsed")
+
+ client.end()
+ })
+ it("Testing pet model", function(client){
+ modelWrapper.waitForElementVisible("@petModel")
+ .click("@petModelCallapse")
+ .assert.cssClassNotPresent("@petModelCallapse", "callapsed")
+
+ client.end()
+ })
+ it("Testing apiResponse model", function(client){
+ modelWrapper.waitForElementVisible("@apiResponseModel")
+ .click("@apiResponseModelCallapse")
+ .assert.cssClassNotPresent("@apiResponseModelCallapse", "callapsed")
+
+ client.end()
+ })
+})
diff --git a/test/e2e/scenarios/operations/pet.js b/test/e2e/scenarios/operations/pet.js
new file mode 100644
index 00000000..441004c5
--- /dev/null
+++ b/test/e2e/scenarios/operations/pet.js
@@ -0,0 +1,172 @@
+describe("render pet api container", function () {
+ let mainPage
+ let apiWrapper
+ beforeEach(function (client, done) {
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+
+ client.waitForElementVisible(".download-url-input", 5000)
+ .pause(5000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+ apiWrapper = mainPage.section.apiWrapper
+
+ done()
+ })
+ afterEach(function (client, done) {
+ done()
+ })
+ it("render section", function (client) {
+ mainPage.expect.section("@apiWrapper").to.be.visible.before(10000)
+ client.end()
+ })
+ it("test rendered pet container", function (client) {
+ apiWrapper.waitForElementVisible("@petAPIWrapper", 5000)
+ .expect.element("@petAPIWrapper").to.be.visible
+
+ client.end()
+ })
+ it("collapse pet wrapper", function (client) {
+ apiWrapper.waitForElementVisible("@petAPIWrapper", 5000)
+ .click("@petAPIWrapperBar")
+ .assert.cssClassNotPresent("@petAPIWrapper", "is-open")
+
+ client.end()
+ })
+ it("render post /pet api container", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationPostContainer", 10000)
+ .assert.containsText("@petOperationPostTitle", "/pet")
+ .click("@petOperationPostCollpase")
+ .waitForElementVisible("@petOperationPostCollapseContainer", 5000)
+ .click("@petOperationPostTryBtn")
+ .waitForElementVisible("@petOperationPostTryText", 1000)
+ .waitForElementVisible("@petOperationPostExecuteBtn", 1000)
+ .click("@petOperationPostTryBtn")
+ .assert.cssClassNotPresent("@petOperationPostTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("Testing post /pet api Mock data", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationPostContainer", 5000)
+ .click("@petOperationPostCollpase")
+ .waitForElementVisible("@petOperationPostCollapseContainer", 5000)
+ .click("@petOperationPostTryBtn")
+ .waitForElementVisible("@petOperationPostExecuteBtn", 1000)
+ .click("@petOperationPostExecuteBtn")
+ .waitForElementVisible("@petOperationPostMockCategoryID", 2000)
+ .assert.containsText("@petOperationPostMockCategoryID", "0")
+ .assert.containsText("@petOperationPostMockCategoryName", "\"string\"")
+ .assert.containsText("@petOperationPostMockName", "\"doggie\"")
+ .assert.containsText("@petOperationPostTagID", "0")
+ .assert.containsText("@petOperationPostTagName", "\"string\"")
+ .assert.containsText("@petOperationPostStatus", "\"available\"")
+ .click("@petOperationPostTryBtn")
+ .assert.cssClassNotPresent("@petOperationPostTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("render put /pet api container", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationPutContainer", 5000)
+ .assert.containsText("@petOperationPutTitle", "/pet")
+ .click("@petOperationPutCollpase")
+ .waitForElementVisible("@petOperationPutCollapseContainer", 3000)
+ .click("@petOperationPutTryBtn")
+ .waitForElementVisible("@petOperationPutTryText", 1000)
+ .waitForElementVisible("@petOperationPutExecuteBtn", 1000)
+ .click("@petOperationPutTryBtn")
+ .assert.cssClassNotPresent("@petOperationPutTryBtn", "cancel")
+
+ client.end()
+ })
+ it("Testing put /pet api Mock data", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationPutContainer", 5000)
+ .click("@petOperationPutCollpase")
+ .waitForElementVisible("@petOperationPutCollapseContainer", 3000)
+ .click("@petOperationPutTryBtn")
+ .waitForElementVisible("@petOperationPutExecuteBtn", 1000)
+ .click("@petOperationPutExecuteBtn")
+ .waitForElementVisible("@petOperationPutMockCategoryID")
+ .assert.containsText("@petOperationPutMockCategoryID", "0")
+ .assert.containsText("@petOperationPutMockCategoryName", "\"string\"")
+ .assert.containsText("@petOperationPutMockName", "\"doggie\"")
+ .assert.containsText("@petOperationPutTagID", "0")
+ .assert.containsText("@petOperationPutTagName", "\"string\"")
+ .assert.containsText("@petOperationPutStatus", "\"available\"")
+ .click("@petOperationPutTryBtn")
+ .assert.cssClassNotPresent("@petOperationPutTryBtn", "Cancel")
+
+ client.end()
+ })
+
+ it("render get by tag /pet api container", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationGetByTagContainer", 5000)
+ .assert.containsText("@petOperationGetByTagTitle", "/pet/findByTags")
+ .click("@petOperationGetByTagCollpase")
+ .waitForElementVisible("@petOperationGetByTagCollapseContainer", 3000)
+ .click("@petOperationGetByTagTryBtn")
+ .waitForElementVisible("@petOperationGetByTagTryAdded", 1000)
+ .waitForElementVisible("@petOperationGetByTagExecuteBtn", 1000)
+ .click("@petOperationGetByTagTryBtn")
+ .assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("Testing get by tag /pet api Mock data", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationGetByTagContainer", 5000)
+ .click("@petOperationGetByTagCollpase")
+ .waitForElementVisible("@petOperationGetByTagCollapseContainer", 3000)
+ .click("@petOperationGetByTagTryBtn")
+ .waitForElementVisible("@petOperationGetByTagExecuteBtn", 1000)
+ .click("@petOperationGetByTagExecuteBtn")
+ .waitForElementVisible("@petOperationGetByTagMockCategoryID")
+ .assert.containsText("@petOperationGetByTagMockCategoryID", "0")
+ .assert.containsText("@petOperationGetByTagMockCategoryName", "\"string\"")
+ .assert.containsText("@petOperationGetByTagMockName", "\"doggie\"")
+ .assert.containsText("@petOperationGetByTagTagID", "0")
+ .assert.containsText("@petOperationGetByTagTagName", "\"string\"")
+ .assert.containsText("@petOperationGetByTagStatus", "\"available\"")
+ .click("@petOperationGetByTagTryBtn")
+ .assert.cssClassNotPresent("@petOperationGetByTagTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("render delete /pet api container", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationDeleteContainer")
+ .assert.containsText("@petOperationDeleteTitle", "/pet/{petId}")
+ .click("@petOperationDeleteCollpase")
+ .waitForElementVisible("@petOperationDeleteCollapseContainer", 3000)
+ .click("@petOperationDeleteTryBtn")
+ .waitForElementVisible("@petOperationDeleteExecuteBtn", 1000)
+ .click("@petOperationDeleteTryBtn")
+ .assert.cssClassNotPresent("@petOperationDeleteTryBtn", "cancel")
+
+ client.end()
+ })
+ it("Testing delete /pet api Mock data", function (client) {
+ apiWrapper.waitForElementVisible("@petOperationDeleteContainer", 3000)
+ .click("@petOperationDeleteCollpase")
+ .waitForElementVisible("@petOperationDeleteCollapseContainer", 3000)
+ .click("@petOperationDeleteTryBtn")
+ .waitForElementVisible("@petOperationDeleteExecuteBtn", 1000)
+ .click("@petOperationDeleteExecuteBtn")
+ .waitForElementVisible("@petOperationDeleteMockCategoryID")
+ .assert.containsText("@petOperationDeleteMockCategoryID", "0")
+ .assert.containsText("@petOperationDeleteMockCategoryName", "\"string\"")
+ .assert.containsText("@petOperationDeleteMockName", "\"doggie\"")
+ .assert.containsText("@petOperationDeleteTagID", "0")
+ .assert.containsText("@petOperationDeleteTagName", "\"string\"")
+ .assert.containsText("@petOperationDeleteStatus", "\"available\"")
+ .click("@petOperationDeleteTryBtn")
+ .assert.cssClassNotPresent("@petOperationDeleteTryBtn", "cancel")
+
+ client.end()
+ })
+})
\ No newline at end of file
diff --git a/test/e2e/scenarios/operations/store.js b/test/e2e/scenarios/operations/store.js
new file mode 100644
index 00000000..7dbcbc24
--- /dev/null
+++ b/test/e2e/scenarios/operations/store.js
@@ -0,0 +1,113 @@
+describe("render store api container", function(){
+ let mainPage
+ let apiWrapper
+ beforeEach( function(client, done){
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+
+ client.waitForElementVisible(".download-url-input", 5000)
+ .pause(3000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+ apiWrapper = mainPage.section.apiWrapper
+
+ done()
+ })
+ afterEach(function (client, done) {
+ done()
+ })
+ it("test rendered store container", function(client){
+ apiWrapper.waitForElementVisible("@storeAPIWrapper", 5000)
+ .expect.element("@storeAPIWrapper").to.be.visible
+
+ client.end()
+ })
+ it("callapse store wrapper", function(client){
+ apiWrapper.waitForElementVisible("@storeAPIWrapper", 5000)
+ .click("@storeAPIWrapperBar")
+ .assert.cssClassNotPresent("@storeAPIWrapper", "is-open")
+
+ client.end()
+ })
+ it("render get /store/inventory api container", function (client) {
+ apiWrapper.waitForElementVisible("@storeOperationGetContainer", 5000)
+ .assert.containsText("@storeOperationGetTitle", "/store/inventory")
+ .click("@storeOperationGetCollpase")
+ .waitForElementVisible("@storeOperationGetCollapseContainer", 5000)
+ .click("@storeOperationGetTryBtn")
+ .waitForElementVisible("@storeOperationGetExecuteBtn", 1000)
+ .click("@storeOperationGetTryBtn")
+ .assert.cssClassNotPresent("@storeOperationGetTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("Testing get /store/inventory api Mock data ", function (client) {
+ apiWrapper.waitForElementVisible("@storeOperationGetContainer", 5000)
+ .assert.containsText("@storeOperationGetTitle", "/store/inventory")
+ .click("@storeOperationGetCollpase")
+ .waitForElementVisible("@storeOperationGetCollapseContainer", 3000)
+ .click("@storeOperationGetTryBtn")
+ .waitForElementVisible("@storeOperationGetExecuteBtn", 1000)
+ .click("@storeOperationGetExecuteBtn")
+ .waitForElementVisible("@storeOperationResponseProps1")
+ .assert.containsText("@storeOperationResponseProps1", "0")
+ .assert.containsText("@storeOperationResponseProps2", "0")
+ .assert.containsText("@storeOperationResponseProps3", "0")
+ .click("@storeOperationGetTryBtn")
+ .assert.cssClassNotPresent("@storeOperationGetTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("render post /store/order api container", function (client) {
+ apiWrapper.waitForElementVisible("@storeOperationPostContainer")
+ .assert.containsText("@storeOperationPostTitle", "/store/order")
+ .click("@storeOperationPostCollpase")
+ .waitForElementVisible("@storeOperationPostCollapseContainer", 3000)
+ .click("@storeOperationPostTryBtn")
+ .waitForElementVisible("@storeOperationPostExecuteBtn", 1000)
+ .click("@storeOperationPostTryBtn")
+ .assert.cssClassNotPresent("@storeOperationPostTryBtn", "cancel")
+
+ client.end()
+ })
+
+ it("Testing post /store/order api Mock Data", function (client) {
+ apiWrapper.waitForElementVisible("@storeOperationPostContainer")
+ .assert.containsText("@storeOperationPostTitle", "/store/order")
+ .click("@storeOperationPostCollpase")
+ .waitForElementVisible("@storeOperationPostCollapseContainer", 3000)
+ .click("@storeOperationPostTryBtn")
+ .waitForElementVisible("@storeOperationPostExecuteBtn", 1000)
+ .click("@storeOperationPostExecuteBtn")
+ .waitForElementVisible("@storeOperationPostResponseId")
+ .assert.containsText("@storeOperationPostResponseId", "0")
+ .assert.containsText("@storeOperationPostResponsePetId", "0")
+ .assert.containsText("@storeOperationPostResponseQuantity", "0")
+ .assert.containsText("@storeOperationPostResponseStatus", "placed")
+ .assert.containsText("@storeOperationPostResponseComplete", "false")
+ .click("@storeOperationPostTryBtn")
+ .assert.cssClassNotPresent("@storeOperationPostTryBtn", "cancel")
+
+ client.end()
+ })
+ it("render delete /store/order/{orderId} api container", function (client) {
+ apiWrapper.waitForElementVisible("@storeOperationDeleteContainer")
+ .assert.containsText("@storeOperationDeleteTitle", "/store/order/{orderId}")
+ .click("@storeOperationDeleteCollpase")
+ .waitForElementVisible("@storeOperationDeleteCollapseContainer", 3000)
+ .click("@storeOperationDeleteTryBtn")
+ .waitForElementVisible("@storeOperationDeleteExecuteBtn", 1000)
+ .click("@storeOperationDeleteExecuteBtn")
+ .waitForElementVisible("@storeOperationGetResponseHeaders", "content-type: application/xml")
+ .click("@storeOperationDeleteTryBtn")
+ .assert.cssClassNotPresent("@storeOperationDeleteTryBtn", "cancel")
+
+ client.end()
+ })
+})
\ No newline at end of file
diff --git a/test/e2e/scenarios/operations/user.js b/test/e2e/scenarios/operations/user.js
new file mode 100644
index 00000000..e84984b7
--- /dev/null
+++ b/test/e2e/scenarios/operations/user.js
@@ -0,0 +1,94 @@
+describe("render user api container", function(){
+ let mainPage
+ let apiWrapper
+ beforeEach( function(client, done){
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+
+ client.waitForElementVisible(".download-url-input", 5000)
+ .pause(5000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+ apiWrapper = mainPage.section.apiWrapper
+
+ done()
+ })
+ afterEach(function (client, done) {
+ done()
+ })
+ it("test rendered user container", function(client){
+ apiWrapper.waitForElementVisible("@userAPIWrapper", 5000)
+ .expect.element("@userAPIWrapper").to.be.visible
+
+ client.end()
+ })
+ it("callapse user wrapper", function(client){
+ apiWrapper.waitForElementVisible("@userAPIWrapper", 5000)
+ .click("@userAPIWrapperBar")
+ .assert.cssClassNotPresent("@userAPIWrapper", "is-open")
+
+ client.end()
+ })
+ it("render put /user/{username} api container", function (client) {
+ apiWrapper.waitForElementVisible("@userOperationPutContainer", 5000)
+ .assert.containsText("@userOperationPutTitle", "/user/{username}")
+ .click("@userOperationPutCollpase")
+ .waitForElementVisible("@userOperationPutCollapseContainer", 3000)
+ .click("@userOperationPutTryBtn")
+ .waitForElementVisible("@userOperationPutExecuteBtn", 1000)
+ .click("@userOperationPutTryBtn")
+ .assert.cssClassNotPresent("@userOperationPutTryBtn", "cancel")
+
+ client.end()
+ })
+ it("Test put /user/{username} api Mock data", function (client) {
+ apiWrapper.waitForElementVisible("@userOperationPutContainer", 5000)
+ .assert.containsText("@userOperationPutTitle", "/user/{username}")
+ .click("@userOperationPutCollpase")
+ .waitForElementVisible("@userOperationPutCollapseContainer", 3000)
+ .click("@userOperationPutTryBtn")
+ .waitForElementVisible("@userOperationPutParameter")
+ .setValue("@userOperationPutParameter", "123")
+ .waitForElementVisible("@userOperationPutExecuteBtn", 1000)
+ .click("userOperationPutExecuteBtn")
+ .waitForElementVisible("@userOperationPutResponseHeader")
+ .assert.containsText("@userOperationPutResponseHeader", "content-type: application/xml")
+ .click("@userOperationPutTryBtn")
+ .assert.cssClassNotPresent("@userOperationPutTryBtn", "cancel")
+
+ client.end()
+ })
+ it("render delete /user/{username} api container", function (client) {
+ apiWrapper.waitForElementVisible("@userOperationDeleteContainer", 5000)
+ .assert.containsText("@userOperationDeleteTitle", "/user/{username}")
+ .click("@userOperationDeleteCollpase")
+ .waitForElementVisible("@userOperationDeleteCollapseContainer", 3000)
+ .click("@userOperationDeleteTryBtn")
+ .waitForElementVisible("@userOperationDeleteExecuteBtn", 1000)
+ .click("@userOperationDeleteTryBtn")
+ .assert.cssClassNotPresent("@userOperationDeleteTryBtn", "cancel")
+
+ client.end()
+ })
+ it("Test delete /user/{username} api Mock data", function (client) {
+ apiWrapper.waitForElementVisible("@userOperationDeleteContainer", 5000)
+ .assert.containsText("@userOperationDeleteTitle", "/user/{username}")
+ .click("@userOperationDeleteCollpase")
+ .waitForElementVisible("@userOperationDeleteCollapseContainer", 3000)
+ .click("@userOperationDeleteTryBtn")
+ .waitForElementVisible("@userOperationDeleteParameter")
+ .setValue("@userOperationDeleteParameter", "123")
+ .waitForElementVisible("@userOperationDeleteExecuteBtn", 1000)
+ .click("userOperationDeleteExecuteBtn")
+ .waitForElementVisible("@userOperationDeleteResponseHeader")
+ .assert.containsText("@userOperationDeleteResponseHeader", "content-type: application/xml")
+ .click("@userOperationDeleteTryBtn")
+ .assert.cssClassNotPresent("@userOperationDeleteTryBtn", "cancel")
+
+ client.end()
+ })
+})
\ No newline at end of file
diff --git a/test/e2e/scenarios/schemeContainer.js b/test/e2e/scenarios/schemeContainer.js
new file mode 100644
index 00000000..51a309b1
--- /dev/null
+++ b/test/e2e/scenarios/schemeContainer.js
@@ -0,0 +1,52 @@
+describe("Render scheme", function () {
+ let mainPage
+ let schemeContainer
+ beforeEach(function (client, done) {
+
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+
+ schemeContainer = mainPage.section.schemeContainer
+
+ client.waitForElementVisible(".download-url-input", 5000)
+ .pause(5000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+
+ done()
+ })
+
+ it("render section", function (client) {
+ mainPage.expect.section("@schemeContainer").to.be.visible.before(5000)
+
+ client.end()
+ })
+ it("render scheme option", function (client) {
+ schemeContainer.waitForElementVisible("@httpOption", 5000)
+ .expect.element("@httpOption").to.be.selected
+
+ client.end()
+ })
+
+ it("render authorized button", function (client) {
+ schemeContainer.waitForElementVisible("@btnAuthorize", 5000)
+ .expect.element("@btnAuthorize").to.be.visible
+
+ client.end()
+ })
+ it("render click event", function(client) {
+ schemeContainer.waitForElementVisible("@btnAuthorize", 5000)
+ .click("@btnAuthorize")
+ .assert.visible("@authorizationModal")
+ .assert.containsText("@appName", "Application: your-app-name")
+ .assert.containsText("@authorizationUrl", "http://petstore.swagger.io/oauth/dialog")
+ .assert.containsText("@flow", "implicit")
+ .assert.value("@inputClientID", "your-client-id")
+
+ client.end()
+ })
+})
\ No newline at end of file
diff --git a/test/e2e/scenarios/topbar.js b/test/e2e/scenarios/topbar.js
new file mode 100644
index 00000000..d7a17efe
--- /dev/null
+++ b/test/e2e/scenarios/topbar.js
@@ -0,0 +1,52 @@
+describe("initial render", function () {
+ let mainPage
+ describe("for topbar", function () {
+ let topbar
+ before(function (client, done) {
+ done()
+ })
+
+ after(function (client, done) {
+ client.end(function () {
+ done()
+ })
+ })
+
+ afterEach(function (client, done) {
+ done()
+ })
+
+ beforeEach(function (client, done) {
+ mainPage = client
+ .url("localhost:3200")
+ .page.main()
+
+ topbar = mainPage.section.topbar
+
+ client.waitForElementVisible(".download-url-input", 10000)
+ .pause(5000)
+ .clearValue(".download-url-input")
+ .setValue(".download-url-input", "http://localhost:3200/test-specs/petstore.json")
+ .click("button.download-url-button")
+ .pause(1000)
+
+ done()
+ })
+
+ it("renders section", function (client) {
+ mainPage.expect.section("@topbar").to.be.visible
+ client.end()
+ })
+
+ it("renders input box", function (client) {
+ topbar.expect.element("@inputBox").to.be.visible
+ client.end()
+ })
+
+ it("renders explore button", function (client) {
+ topbar.expect.element("@btnExplore").to.be.visible
+
+ client.end()
+ })
+ })
+})
diff --git a/test/e2e/specs/petstore.json b/test/e2e/specs/petstore.json
new file mode 100644
index 00000000..2d161887
--- /dev/null
+++ b/test/e2e/specs/petstore.json
@@ -0,0 +1,1043 @@
+{
+ "swagger":"2.0",
+ "info":{
+ "description":"This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
+ "version":"1.0.0",
+ "title":"Swagger Petstore",
+ "termsOfService":"http://swagger.io/terms/",
+ "contact":{
+ "email":"apiteam@swagger.io"
+ },
+ "license":{
+ "name":"Apache 2.0",
+ "url":"http://www.apache.org/licenses/LICENSE-2.0.html"
+ }
+ },
+ "host":"localhost:3204",
+ "basePath":"/",
+ "tags":[
+ {
+ "name":"pet",
+ "description":"Everything about your Pets",
+ "externalDocs":{
+ "description":"Find out more",
+ "url":"http://swagger.io"
+ }
+ },
+ {
+ "name":"store",
+ "description":"Access to Petstore orders"
+ },
+ {
+ "name":"user",
+ "description":"Operations about user",
+ "externalDocs":{
+ "description":"Find out more about our store",
+ "url":"http://swagger.io"
+ }
+ }
+ ],
+ "schemes":[
+ "http"
+ ],
+ "paths":{
+ "/pet":{
+ "post":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Add a new pet to the store",
+ "description":"",
+ "operationId":"addPet",
+ "consumes":[
+ "application/json",
+ "application/xml"
+ ],
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "in":"body",
+ "name":"body",
+ "description":"Pet object that needs to be added to the store",
+ "required":true,
+ "schema":{
+ "$ref":"#/definitions/Pet"
+ }
+ }
+ ],
+ "responses":{
+ "405":{
+ "description":"Invalid input"
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "put":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Update an existing pet",
+ "description":"",
+ "operationId":"updatePet",
+ "consumes":[
+ "application/json",
+ "application/xml"
+ ],
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "in":"body",
+ "name":"body",
+ "description":"Pet object that needs to be added to the store",
+ "required":true,
+ "schema":{
+ "$ref":"#/definitions/Pet"
+ }
+ }
+ ],
+ "responses":{
+ "400":{
+ "description":"Invalid ID supplied"
+ },
+ "404":{
+ "description":"Pet not found"
+ },
+ "405":{
+ "description":"Validation exception"
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/findByStatus":{
+ "get":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Finds Pets by status",
+ "description":"Multiple status values can be provided with comma separated strings",
+ "operationId":"findPetsByStatus",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"status",
+ "in":"query",
+ "description":"Status values that need to be considered for filter",
+ "required":true,
+ "type":"array",
+ "items":{
+ "type":"string",
+ "enum":[
+ "available",
+ "pending",
+ "sold"
+ ],
+ "default":"available"
+ },
+ "collectionFormat":"multi"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "type":"array",
+ "items":{
+ "$ref":"#/definitions/Pet"
+ }
+ }
+ },
+ "400":{
+ "description":"Invalid status value"
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/findByTags":{
+ "get":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Finds Pets by tags",
+ "description":"Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
+ "operationId":"findPetsByTags",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"tags",
+ "in":"query",
+ "description":"Tags to filter by",
+ "required":true,
+ "type":"array",
+ "items":{
+ "type":"string"
+ },
+ "collectionFormat":"multi"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "type":"array",
+ "items":{
+ "$ref":"#/definitions/Pet"
+ }
+ }
+ },
+ "400":{
+ "description":"Invalid tag value"
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ],
+ "deprecated":true
+ }
+ },
+ "/pet/{petId}":{
+ "get":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Find pet by ID",
+ "description":"Returns a single pet",
+ "operationId":"getPetById",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"petId",
+ "in":"path",
+ "description":"ID of pet to return",
+ "required":true,
+ "type":"integer",
+ "format":"int64"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "$ref":"#/definitions/Pet"
+ }
+ },
+ "400":{
+ "description":"Invalid ID supplied"
+ },
+ "404":{
+ "description":"Pet not found"
+ }
+ },
+ "security":[
+ {
+ "api_key":[
+
+ ]
+ }
+ ]
+ },
+ "post":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Updates a pet in the store with form data",
+ "description":"",
+ "operationId":"updatePetWithForm",
+ "consumes":[
+ "application/x-www-form-urlencoded"
+ ],
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"petId",
+ "in":"path",
+ "description":"ID of pet that needs to be updated",
+ "required":true,
+ "type":"integer",
+ "format":"int64"
+ },
+ {
+ "name":"name",
+ "in":"formData",
+ "description":"Updated name of the pet",
+ "required":false,
+ "type":"string"
+ },
+ {
+ "name":"status",
+ "in":"formData",
+ "description":"Updated status of the pet",
+ "required":false,
+ "type":"string"
+ }
+ ],
+ "responses":{
+ "405":{
+ "description":"Invalid input"
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "delete":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"Deletes a pet",
+ "description":"",
+ "operationId":"deletePet",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"api_key",
+ "in":"header",
+ "required":false,
+ "type":"string"
+ },
+ {
+ "name":"petId",
+ "in":"path",
+ "description":"Pet id to delete",
+ "required":true,
+ "type":"integer",
+ "format":"int64"
+ }
+ ],
+ "responses":{
+ "400":{
+ "description":"Invalid ID supplied"
+ },
+ "404":{
+ "description":"Pet not found"
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/{petId}/uploadImage":{
+ "post":{
+ "tags":[
+ "pet"
+ ],
+ "summary":"uploads an image",
+ "description":"",
+ "operationId":"uploadFile",
+ "consumes":[
+ "multipart/form-data"
+ ],
+ "produces":[
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"petId",
+ "in":"path",
+ "description":"ID of pet to update",
+ "required":true,
+ "type":"integer",
+ "format":"int64"
+ },
+ {
+ "name":"additionalMetadata",
+ "in":"formData",
+ "description":"Additional data to pass to server",
+ "required":false,
+ "type":"string"
+ },
+ {
+ "name":"file",
+ "in":"formData",
+ "description":"file to upload",
+ "required":false,
+ "type":"file"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "$ref":"#/definitions/ApiResponse"
+ }
+ }
+ },
+ "security":[
+ {
+ "petstore_auth":[
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/store/inventory":{
+ "get":{
+ "tags":[
+ "store"
+ ],
+ "summary":"Returns pet inventories by status",
+ "description":"Returns a map of status codes to quantities",
+ "operationId":"getInventory",
+ "produces":[
+ "application/json"
+ ],
+ "parameters":[
+
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "type":"object",
+ "additionalProperties":{
+ "type":"integer",
+ "format":"int32"
+ }
+ }
+ }
+ },
+ "security":[
+ {
+ "api_key":[
+
+ ]
+ }
+ ]
+ }
+ },
+ "/store/order":{
+ "post":{
+ "tags":[
+ "store"
+ ],
+ "summary":"Place an order for a pet",
+ "description":"",
+ "operationId":"placeOrder",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "in":"body",
+ "name":"body",
+ "description":"order placed for purchasing the pet",
+ "required":true,
+ "schema":{
+ "$ref":"#/definitions/Order"
+ }
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "$ref":"#/definitions/Order"
+ }
+ },
+ "400":{
+ "description":"Invalid Order"
+ }
+ }
+ }
+ },
+ "/store/order/{orderId}":{
+ "get":{
+ "tags":[
+ "store"
+ ],
+ "summary":"Find purchase order by ID",
+ "description":"For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
+ "operationId":"getOrderById",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"orderId",
+ "in":"path",
+ "description":"ID of pet that needs to be fetched",
+ "required":true,
+ "type":"integer",
+ "maximum":10.0,
+ "minimum":1.0,
+ "format":"int64"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "$ref":"#/definitions/Order"
+ }
+ },
+ "400":{
+ "description":"Invalid ID supplied"
+ },
+ "404":{
+ "description":"Order not found"
+ }
+ }
+ },
+ "delete":{
+ "tags":[
+ "store"
+ ],
+ "summary":"Delete purchase order by ID",
+ "description":"For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
+ "operationId":"deleteOrder",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"orderId",
+ "in":"path",
+ "description":"ID of the order that needs to be deleted",
+ "required":true,
+ "type":"integer",
+ "minimum":1.0,
+ "format":"int64"
+ }
+ ],
+ "responses":{
+ "400":{
+ "description":"Invalid ID supplied"
+ },
+ "404":{
+ "description":"Order not found"
+ }
+ }
+ }
+ },
+ "/user":{
+ "post":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Create user",
+ "description":"This can only be done by the logged in user.",
+ "operationId":"createUser",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "in":"body",
+ "name":"body",
+ "description":"Created user object",
+ "required":true,
+ "schema":{
+ "$ref":"#/definitions/User"
+ }
+ }
+ ],
+ "responses":{
+ "default":{
+ "description":"successful operation"
+ }
+ }
+ }
+ },
+ "/user/createWithArray":{
+ "post":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Creates list of users with given input array",
+ "description":"",
+ "operationId":"createUsersWithArrayInput",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "in":"body",
+ "name":"body",
+ "description":"List of user object",
+ "required":true,
+ "schema":{
+ "type":"array",
+ "items":{
+ "$ref":"#/definitions/User"
+ }
+ }
+ }
+ ],
+ "responses":{
+ "default":{
+ "description":"successful operation"
+ }
+ }
+ }
+ },
+ "/user/createWithList":{
+ "post":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Creates list of users with given input array",
+ "description":"",
+ "operationId":"createUsersWithListInput",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "in":"body",
+ "name":"body",
+ "description":"List of user object",
+ "required":true,
+ "schema":{
+ "type":"array",
+ "items":{
+ "$ref":"#/definitions/User"
+ }
+ }
+ }
+ ],
+ "responses":{
+ "default":{
+ "description":"successful operation"
+ }
+ }
+ }
+ },
+ "/user/login":{
+ "get":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Logs user into the system",
+ "description":"",
+ "operationId":"loginUser",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"username",
+ "in":"query",
+ "description":"The user name for login",
+ "required":true,
+ "type":"string"
+ },
+ {
+ "name":"password",
+ "in":"query",
+ "description":"The password for login in clear text",
+ "required":true,
+ "type":"string"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "type":"string"
+ },
+ "headers":{
+ "X-Rate-Limit":{
+ "type":"integer",
+ "format":"int32",
+ "description":"calls per hour allowed by the user"
+ },
+ "X-Expires-After":{
+ "type":"string",
+ "format":"date-time",
+ "description":"date in UTC when token expires"
+ }
+ }
+ },
+ "400":{
+ "description":"Invalid username/password supplied"
+ }
+ }
+ }
+ },
+ "/user/logout":{
+ "get":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Logs out current logged in user session",
+ "description":"",
+ "operationId":"logoutUser",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+
+ ],
+ "responses":{
+ "default":{
+ "description":"successful operation"
+ }
+ }
+ }
+ },
+ "/user/{username}":{
+ "get":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Get user by user name",
+ "description":"",
+ "operationId":"getUserByName",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"username",
+ "in":"path",
+ "description":"The name that needs to be fetched. Use user1 for testing. ",
+ "required":true,
+ "type":"string"
+ }
+ ],
+ "responses":{
+ "200":{
+ "description":"successful operation",
+ "schema":{
+ "$ref":"#/definitions/User"
+ }
+ },
+ "400":{
+ "description":"Invalid username supplied"
+ },
+ "404":{
+ "description":"User not found"
+ }
+ }
+ },
+ "put":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Updated user",
+ "description":"This can only be done by the logged in user.",
+ "operationId":"updateUser",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"username",
+ "in":"path",
+ "description":"name that need to be updated",
+ "required":true,
+ "type":"string"
+ },
+ {
+ "in":"body",
+ "name":"body",
+ "description":"Updated user object",
+ "required":true,
+ "schema":{
+ "$ref":"#/definitions/User"
+ }
+ }
+ ],
+ "responses":{
+ "400":{
+ "description":"Invalid user supplied"
+ },
+ "404":{
+ "description":"User not found"
+ }
+ }
+ },
+ "delete":{
+ "tags":[
+ "user"
+ ],
+ "summary":"Delete user",
+ "description":"This can only be done by the logged in user.",
+ "operationId":"deleteUser",
+ "produces":[
+ "application/xml",
+ "application/json"
+ ],
+ "parameters":[
+ {
+ "name":"username",
+ "in":"path",
+ "description":"The name that needs to be deleted",
+ "required":true,
+ "type":"string"
+ }
+ ],
+ "responses":{
+ "400":{
+ "description":"Invalid username supplied"
+ },
+ "404":{
+ "description":"User not found"
+ }
+ }
+ }
+ }
+ },
+ "securityDefinitions":{
+ "petstore_auth":{
+ "type":"oauth2",
+ "authorizationUrl":"http://petstore.swagger.io/oauth/dialog",
+ "flow":"implicit",
+ "scopes":{
+ "write:pets":"modify pets in your account",
+ "read:pets":"read your pets"
+ }
+ },
+ "api_key":{
+ "type":"apiKey",
+ "name":"api_key",
+ "in":"header"
+ }
+ },
+ "definitions":{
+ "Order":{
+ "type":"object",
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "petId":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "quantity":{
+ "type":"integer",
+ "format":"int32"
+ },
+ "shipDate":{
+ "type":"string",
+ "format":"date-time"
+ },
+ "status":{
+ "type":"string",
+ "description":"Order Status",
+ "enum":[
+ "placed",
+ "approved",
+ "delivered"
+ ]
+ },
+ "complete":{
+ "type":"boolean",
+ "default":false
+ }
+ },
+ "xml":{
+ "name":"Order"
+ }
+ },
+ "Category":{
+ "type":"object",
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "name":{
+ "type":"string"
+ }
+ },
+ "xml":{
+ "name":"Category"
+ }
+ },
+ "User":{
+ "type":"object",
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "username":{
+ "type":"string"
+ },
+ "firstName":{
+ "type":"string"
+ },
+ "lastName":{
+ "type":"string"
+ },
+ "email":{
+ "type":"string"
+ },
+ "password":{
+ "type":"string"
+ },
+ "phone":{
+ "type":"string"
+ },
+ "userStatus":{
+ "type":"integer",
+ "format":"int32",
+ "description":"User Status"
+ }
+ },
+ "xml":{
+ "name":"User"
+ }
+ },
+ "Tag":{
+ "type":"object",
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "name":{
+ "type":"string"
+ }
+ },
+ "xml":{
+ "name":"Tag"
+ }
+ },
+ "Pet":{
+ "type":"object",
+ "required":[
+ "name",
+ "photoUrls"
+ ],
+ "properties":{
+ "id":{
+ "type":"integer",
+ "format":"int64"
+ },
+ "category":{
+ "$ref":"#/definitions/Category"
+ },
+ "name":{
+ "type":"string",
+ "example":"doggie"
+ },
+ "photoUrls":{
+ "type":"array",
+ "xml":{
+ "name":"photoUrl",
+ "wrapped":true
+ },
+ "items":{
+ "type":"string"
+ }
+ },
+ "tags":{
+ "type":"array",
+ "xml":{
+ "name":"tag",
+ "wrapped":true
+ },
+ "items":{
+ "$ref":"#/definitions/Tag"
+ }
+ },
+ "status":{
+ "type":"string",
+ "description":"pet status in the store",
+ "enum":[
+ "available",
+ "pending",
+ "sold"
+ ]
+ }
+ },
+ "xml":{
+ "name":"Pet"
+ }
+ },
+ "ApiResponse":{
+ "type":"object",
+ "properties":{
+ "code":{
+ "type":"integer",
+ "format":"int32"
+ },
+ "type":{
+ "type":"string"
+ },
+ "message":{
+ "type":"string"
+ }
+ }
+ }
+ },
+ "externalDocs":{
+ "description":"Find out more about Swagger",
+ "url":"http://swagger.io"
+ }
+}
\ No newline at end of file
diff --git a/webpack-watch.config.js b/webpack-watch.config.js
index ed5c711c..2c4bbc94 100644
--- a/webpack-watch.config.js
+++ b/webpack-watch.config.js
@@ -1,3 +1,8 @@
const config = require("./webpack-dist.config.js")
+config.plugins = config.plugins.filter(plugin => {
+ // Disable minification
+ return plugin.constructor.name !== "UglifyJsPlugin"
+})
+
module.exports = config