Compare commits

...
169 Commits
Author SHA1 Message Date
Kyle 72c8887d7b Merge pull request #3595 from shockey/v/3.1.6
v3.1.6
2017-08-18 18:51:10 -07:00
Kyle Shockey bd3d00c182 v3.1.6 2017-08-18 18:43:52 -07:00
Kyle ff4930b235 Merge pull request #3593 from oysteinsigholt/fix-domNodeMerge
Fixes #3589 - Remove domNode from deepExtend
2017-08-18 09:49:10 -07:00
Øystein Sigholt 7287c74a3a Remove domNode from deepExtend 2017-08-18 18:27:16 +02:00
Kyle 668827b9d2 Merge pull request #3534 from gilbode/ft/request_interceptor
Add support for requestInterceptor / responseInterceptor.
2017-08-17 17:45:05 -07:00
Mike Gilbode 087ed20384 Add support for requestInterceptor / responseInterceptor.
- Display mutated requests from request interceptor in curl output in UI.
  Put this behind showMutatedRequest flag so that the mutation can be
  silent.
- Document requestInterceptor, responseInterceptor and showMutatedRequest
  in README.md
- Add tests
2017-08-13 01:14:41 -04:00
Kyle c88c8c32f3 Merge pull request #3564 from shockey/v/3.1.5
v3.1.5
2017-08-11 21:44:41 -07:00
Kyle Shockey f6691d40c7 v3.1.5 2017-08-11 21:36:35 -07:00
Kyle f599f84f01 Merge pull request #3562 from owenconti/ft/react-perf-permanent
Introduce React.Perf in all non-production builds.
2017-08-11 17:41:49 -07:00
Kyle 87f1a975f7 Merge branch 'master' into ft/react-perf-permanent 2017-08-11 17:34:00 -07:00
Kyle e43c4507a8 Merge pull request #3418 from aleatham/xlink-deprecated
Added href attribute to <use> tags with deprecated xlinkHref attribute.
2017-08-11 16:53:01 -07:00
Kyle 08bb9fb7f3 Merge branch 'master' into xlink-deprecated 2017-08-11 16:45:53 -07:00
Kyle c1f37035bb Use react semver mask for react-addons-perf 2017-08-11 16:28:10 -07:00
Owen Conti c237f25638 Introduce React.Perf in all non-production builds. 2017-08-11 15:55:19 -06:00
Kyle 8bf0f42c5d Merge pull request #3557 from shockey/bug/3268-oas3-param-types
Display OAS3 parameter types
2017-08-10 23:11:18 -07:00
Kyle 2a280eb9e1 Merge branch 'master' into bug/3268-oas3-param-types 2017-08-10 23:06:48 -07:00
Kyle Shockey 1eab4b3b20 Display OAS3 parameter types 2017-08-10 22:55:41 -07:00
Kyle d4dd197f44 Merge pull request #3553 from swagger-api/feature/headerfix
Changed radius on input in topbar
2017-08-10 21:36:37 -07:00
Kyle 447fb678df Merge branch 'master' into feature/headerfix 2017-08-10 21:17:44 -07:00
Kyle e1a49ee039 Merge pull request #3454 from shockey/3014-contributing-guidelines
Add CONTRIBUTING.md
2017-08-10 20:55:46 -07:00
Kyle b5e2fd58d6 Merge branch 'master' into 3014-contributing-guidelines 2017-08-10 18:54:27 -07:00
Kyle 10db6db2d0 Merge pull request #3520 from shockey/bug/3447-write-only
Filter writeOnly fields in relevant places
2017-08-10 18:53:43 -07:00
Kyle 670ecc5ed1 Merge branch 'master' into 3014-contributing-guidelines 2017-08-10 18:42:23 -07:00
Kyle eb159232f9 Shorten commiting section 2017-08-10 18:42:09 -07:00
Kyle e67af44a19 Merge branch 'master' into bug/3447-write-only 2017-08-10 18:40:30 -07:00
Kyle 6691d9f672 Merge pull request #3556 from shockey/bug/3555-multipart-curl
Fix cURL outputs with formData
2017-08-10 18:40:21 -07:00
Kyle Shockey b464d2c977 pass entire config to recursive sample calls 2017-08-10 18:39:43 -07:00
Kyle 73f17ddf63 Merge branch 'master' into bug/3555-multipart-curl 2017-08-10 18:30:28 -07:00
Kyle Shockey 168e203040 Use hash for body in formData tests
I couldn't find any instances of body being an array when testing
formData with real specs... I think this was a mistake.
2017-08-10 18:27:03 -07:00
Kyle Shockey 964d528735 Replace valueSeq with entrySeq 2017-08-10 18:26:45 -07:00
Kyle c5f5eff900 Merge branch 'master' into bug/3447-write-only 2017-08-10 17:16:51 -07:00
Minasokoni 5aa7f307bf changed radius on input in topbar 2017-08-09 22:47:53 -07:00
Kyle 8de1add244 Merge pull request #3552 from shockey/bug/3541-3470-schemes
Fix global state issues with Schemes component
2017-08-09 18:07:43 -07:00
Kyle Shockey 049e227c3c Add small comment to test 2017-08-09 17:44:36 -07:00
Kyle e72e853e4b Merge branch 'master' into bug/3541-3470-schemes 2017-08-09 17:44:02 -07:00
Kyle Shockey b7a3f10f64 Remove it.only 2017-08-09 17:35:56 -07:00
Kyle Shockey 9747559529 operationScheme -> currentScheme 2017-08-09 17:35:33 -07:00
Kyle Shockey 99c610f224 Mark operationScheme as required prop 2017-08-09 17:10:39 -07:00
Kyle Shockey 9dee2daa14 Fix global state issues with Schemes component 2017-08-09 17:06:48 -07:00
Kyle 383d01d3bd Merge pull request #3550 from swagger-api/issue-template-minor-change
Add note about large specs to issue template
2017-08-09 16:08:19 -07:00
Kyle f9d6e77091 Update issue_template.md 2017-08-09 16:03:28 -07:00
Kyle 66d7638a91 Add note about large specs to issue template [ci skip] 2017-08-09 16:01:34 -07:00
Kyle 53466556ef Merge pull request #3549 from swagger-api/updated-issue-template
Update issue template
2017-08-09 15:42:57 -07:00
Kyle c35a904918 spec -> API definition 2017-08-09 15:38:49 -07:00
Kyle ff8ac0d42e LESS typos 2017-08-09 15:37:09 -07:00
Kyle 70f53e5d62 Update issue template
Lifted from the wonderful Babel issue template: https://github.com/babel/babel/issues/new
2017-08-09 15:35:11 -07:00
Kyle Shockey be293de220 Disable minification in npm run watch 2017-08-09 13:55:44 -07:00
Kyle Shockey 35013d0945 Merge branch 'master' of github.com:swagger-api/swagger-ui 2017-08-08 20:15:17 -07:00
Kyle Shockey 31bf1d3779 MOAR link styling 2017-08-08 20:07:59 -07:00
Kyle 26cab61380 Merge pull request #3543 from shockey/bug/oas3-link-display-issues
Correct funky CSS for links
2017-08-08 19:46:52 -07:00
Kyle Shockey 9bb0cd7689 Correct funky CSS for links 2017-08-08 19:20:28 -07:00
Kyle 8d7f2ddb1c Merge pull request #3265 from RVKen/issue-1334
[1334] integrate nightwatch
2017-08-08 18:24:07 -07:00
Kyle Shockey ed6a4fffb9 initialize mainPage variable (for linter) 2017-08-08 18:10:33 -07:00
Kyle Shockey 49bb139736 1.json -> petstore.json 2017-08-08 18:03:54 -07:00
Kyle Shockey e7bba1c522 Merge branch 'issue-1334' of https://github.com/RVKen/swagger-ui into RVKen-issue-1334 2017-08-08 17:59:16 -07:00
Kyle 15f9cd9612 Ignore any further changes to db.json 2017-08-08 17:57:03 -07:00
Kyle 747d095522 Update README.md 2017-08-08 17:56:21 -07:00
Kyle Shockey 67da84d879 Ignore further changes to db.json 2017-08-08 15:17:25 -07:00
Kenny 543d34d009 write the test in multiple files 2017-08-08 14:08:21 -07:00
Kyle 8c8b98deb9 Merge branch 'master' into issue-1334 2017-08-07 19:32:48 -07:00
Kyle 1fbce1d47a Merge pull request #3529 from shockey/v/3.1.4
v3.1.4: Rebuild dist
2017-08-05 11:27:48 -07:00
Kyle b840826170 Merge branch 'master' into v/3.1.4 2017-08-05 11:24:50 -07:00
Kyle Shockey 1778913cfd Rebuild dist 2017-08-05 11:23:47 -07:00
Kyle 93f1f652ea Merge pull request #3528 from shockey/v/3.1.4
v3.1.4
2017-08-05 11:22:17 -07:00
Kyle Shockey 27616217ab v3.1.4 2017-08-05 10:50:20 -07:00
Kyle Shockey d39464407f Fix incorrect props rest/spreading 2017-08-05 10:48:28 -07:00
Tony Tam 9ed7c700b0 Merge branch 'master' into issue-1334 2017-08-05 10:38:28 +00:00
Kyle 2099ca09e6 Merge pull request #3526 from shockey/v/3.1.3
v3.1.3
2017-08-04 21:46:20 -07:00
Kyle Shockey 95b7adc246 Rebuild dist 2017-08-04 21:38:57 -07:00
Kyle Shockey 4b0b51ab6e v3.1.3 2017-08-04 21:36:13 -07:00
Kyle 08b1f88557 Merge pull request #3354 from owenconti/bug/2903-wrong-font-for-error
Fixes #2903 - Wrong font for errors
2017-08-04 16:41:00 -07:00
Kyle b7575ed8a5 Merge branch 'master' into bug/2903-wrong-font-for-error 2017-08-04 16:37:17 -07:00
Kyle 73662c0aec Merge pull request #3514 from owenconti/bug/3505-schema-title-in-array-schemes
Fixes #3505 - Choose modelName before name in Model component
2017-08-04 16:37:11 -07:00
Kyle dc4e60170d Merge branch 'master' into bug/3505-schema-title-in-array-schemes 2017-08-04 16:33:14 -07:00
Kyle 6af2aae26f Merge pull request #3509 from owenconti/bug/3500-missing-name-for-primitives
Fixes #3500 - Fix missing names for primitive models
2017-08-04 16:32:48 -07:00
Kyle 719db39ac4 Merge branch 'master' into bug/3500-missing-name-for-primitives 2017-08-04 16:27:35 -07:00
Kyle 0113703e16 Merge pull request #3488 from owenconti/bug/3480-model-description-over-the-edge
Fixes #3480 - Overflowing model description.
2017-08-04 16:27:26 -07:00
Kyle 19e09c2296 Merge branch 'master' into bug/3500-missing-name-for-primitives 2017-08-04 16:27:25 -07:00
Kyle 859ae1fd19 Merge branch 'master' into bug/3480-model-description-over-the-edge 2017-08-04 16:23:50 -07:00
Kyle bc62c1c751 Merge pull request #3524 from shockey/bug/3458-oas3-parameter-deprecation
Indicate parameter deprecation
2017-08-04 16:15:02 -07:00
Kyle Shockey 35733b5eb4 Indicate parameter deprecation 2017-08-04 15:39:48 -07:00
Kyle 2733205481 Merge pull request #3522 from swagger-api/ft/oas3
Removed animation as temporary fix
2017-08-04 14:53:52 -07:00
Kyle 0a20d724db Merge branch 'master' into ft/oas3 2017-08-04 14:45:29 -07:00
Kenny c7af68b06d Rehydrate test code 2017-08-04 11:19:02 -07:00
Minasokoni 758a229ac4 removed animation as temporary fix 2017-08-04 01:43:07 -07:00
Kyle Shockey 15b70b6f2d Set writeOnly flags in correct places 2017-08-03 17:42:04 -07:00
Kyle Shockey 9af5d2dc66 Add writeOnly support to sampleFromSchema; add tests for the same 2017-08-03 17:23:16 -07:00
Kyle Shockey 37f9d5aa29 Add tests 2017-08-03 17:13:58 -07:00
Kyle Shockey 5e96821c05 Add writeOnly logic 2017-08-03 17:13:38 -07:00
Kyle 8633372270 Merge pull request #3519 from shockey/bug/editor-1418-oas3-jump-to-model
Create valid paths for model jumping in OAS3
2017-08-03 16:26:31 -07:00
Kyle c664e39908 Update object-model.jsx 2017-08-03 16:22:42 -07:00
Kyle c72c476f4b Merge branch 'master' into bug/editor-1418-oas3-jump-to-model 2017-08-03 16:17:39 -07:00
Kyle Shockey b16907ce6d Create valid paths for model jumping in OAS3 2017-08-03 16:15:47 -07:00
Anna 6233886983 Merge pull request #3481 from domanchi/master
Removing CORS header in request
2017-08-03 17:47:35 +03:00
Aaron Loo 700d547529 merge master 2017-08-03 07:32:32 -07:00
Kyle 103aaa54d5 Merge branch 'master' into bug/3505-schema-title-in-array-schemes 2017-08-02 20:55:24 -07:00
Kyle f375afc742 Merge pull request #3501 from oysteinsigholt/master
Fixes #3492 - Add domNode parameter
2017-08-02 17:10:25 -07:00
Kyle faafe372bd Merge branch 'master' into master 2017-08-02 17:06:49 -07:00
Kyle cd422fe8a7 Merge pull request #3513 from shockey/ft/3490-anyof-oneof-not-models
Support oneOf, anyOf, not
2017-08-02 16:49:39 -07:00
Kyle 2d00766c10 Merge branch 'master' into ft/3490-anyof-oneof-not-models 2017-08-02 16:41:16 -07:00
Owen Conti fb5443601e Fixes #3505 - Choose modelName before name in Model component 2017-08-02 17:39:56 -06:00
Kyle Shockey 4cd88d3360 Support oneOf + anyOf + not 2017-08-02 16:37:57 -07:00
Kyle b8cf502cfc Merge branch 'master' into master 2017-08-02 15:58:34 -07:00
Kyle ab53122271 Merge pull request #3512 from Raincal/patch-1
Remove a duplicate package
2017-08-02 15:56:31 -07:00
Kyle Shockey 1047226ff4 Reshuffle e2e commands (e2e is the top-level command now) 2017-08-02 13:57:25 -07:00
Kenny c38ba45aa0 Fix base url. 2017-08-02 12:39:09 -07:00
Kenny b7bbead9c7 Merge branch 'master' into issue-1334
# Conflicts:
#	.gitignore
#	make-webpack-config.js
2017-08-02 20:14:03 +02:00
Kenny 7cb6bdd7f4 revert dependency 2017-08-02 19:23:07 +02:00
Kenny d0da2a51fa revert dist/ 2017-08-02 19:20:08 +02:00
Raincal 92e5f4f100 Remove a duplicate package 2017-08-02 11:16:59 -05:00
Kenny 8ca88b583f remove legacy code 2017-08-02 10:39:29 +02:00
Ron ad8bad6ddc Merge pull request #3508 from shockey/ft/3397-tags-external-docs
Display tag externalDocs
2017-08-01 22:03:56 -07:00
Kyle c2a1fa9d8f Merge branch 'master' into bug/3500-missing-name-for-primitives 2017-08-01 19:59:28 -07:00
Owen Conti d64dfc4252 Fixes #3500 - Fix missing names for primitive models 2017-08-01 20:46:41 -06:00
Kyle 7c8467652e Merge branch 'master' into ft/3397-tags-external-docs 2017-08-01 19:39:39 -07:00
Kyle Shockey c29e05d726 Display tag externalDocs 2017-08-01 19:34:56 -07:00
Kyle ad4cec0f1f Merge pull request #3380 from TheClimateCorporation/support-basic-auth-for-authorization-code-grant
Support basic auth for authorization code grant
2017-08-01 17:05:12 -07:00
Kyle 470cfe5cad Merge branch 'master' into support-basic-auth-for-authorization-code-grant 2017-08-01 16:57:13 -07:00
Kyle 7927d85e15 Merge pull request #3507 from swagger-api/shockey-patch-1
MOAR OpenAPI specification revisions
2017-08-01 16:56:58 -07:00
Kyle 88a6e075dd Remove useBasicAuthenticationWithAccessCodeGrant
... from `initOAuth` example
2017-08-01 16:54:30 -07:00
Kyle b329b03464 Merge branch 'master' into support-basic-auth-for-authorization-code-grant 2017-08-01 16:52:04 -07:00
shockey 53c11700ba MOAR OpenAPI specification revisions 2017-08-01 16:41:16 -07:00
Kenny 3e212655ae add some test 2017-08-01 09:33:17 -07:00
Kenny 144c8b2eee finish overall test 2017-08-01 09:32:31 -07:00
oysteinsigholt 230f4a8467 add domNode parameter 2017-08-01 11:11:10 +02:00
shockey 6b1d78c6a6 Merge pull request #3497 from shockey/3.1.2-dist-updates
3.1.2: Rebuild dist
2017-07-31 17:32:11 -07:00
Kyle Shockey 0051140fc8 Rebuild dist 2017-07-31 17:25:48 -07:00
Kenny dbe3c3194f writing mock data test for pet 2017-07-31 08:09:16 -07:00
Owen Conti ea75eddcfb Fixes #3480
Change margin-left to padding-left on '&:first-of-type' table cells. Adjust width of table cell to account for padding.
2017-07-30 16:22:49 -06:00
Aaron Loo a04c6240fb Merge branch 'master' of https://github.com/swagger-api/swagger-ui 2017-07-28 10:20:15 -07:00
Aaron Loo 893d0b2cbf updating dist 2017-07-28 10:19:45 -07:00
Aaron Loo 860d356178 remove CORS header in request 2017-07-28 10:15:05 -07:00
shockey 403598ec78 Update CONTRIBUTING.md 2017-07-25 23:13:44 -07:00
Kenny 0e552c2116 Write test for UI 2017-07-25 14:42:39 -07:00
shockey 624f491510 Update CONTRIBUTING.md 2017-07-24 23:39:20 -07:00
Kyle Shockey 962464980f Add information on version branches 2017-07-24 23:34:28 -07:00
Kyle Shockey 09d3f5ad6c Add Github link 2017-07-24 23:31:54 -07:00
Kyle Shockey d95c6523ff Add CONTRIBUTING.md 2017-07-24 23:30:31 -07:00
shockey 71abda66ec Merge branch 'master' into bug/2903-wrong-font-for-error 2017-07-21 20:17:18 -07:00
shockey 4f1772f654 Merge branch 'master' into bug/2903-wrong-font-for-error 2017-07-21 19:19:44 -07:00
shockey cb6b305fc9 Merge branch 'master' into xlink-deprecated 2017-07-20 17:00:25 -07:00
Austin 73f89fc2fd Added href attribute to <use> tags with deprecated xlinkHref attribute. 2017-07-19 20:16:53 -05:00
Owen Conti 24882b69a8 File formatting fixes 2017-07-17 21:15:05 -06:00
Owen Conti 0622bd7179 Revert changes based on @Minasokoni's suggestion 2017-07-17 21:09:25 -06:00
Owen Conti 54b867a9bc Merge branch 'master' into bug/2903-wrong-font-for-error
# Conflicts:
#	dev-helpers/index.html
2017-07-17 18:51:04 -06:00
Eric Turcotte a09e0b8b4a Removed semicolon 2017-07-13 11:16:47 -05:00
Eric Turcotte badfea61c3 Renamed authorizeAccessCodeWithQueryParams->authorizeAccessCodeWithFormParams
since that is technically correct
2017-07-13 10:53:36 -05:00
Eric Turcotte b06971bf81 If config useBasicAuthenticationWithAccessCodeGrant is truthy, send client id
and secret as HTTP basic auth during authorization_code grant
2017-07-12 23:35:34 -05:00
Eric Turcotte fc8ad8168d Renamed authorizeAccessCode() to authorizeAccessCodeWithQueryParams()
Added authorizeAccessCodeWithBasicAuthentication() that sends the client_id and
client_secret using HTTP basic authentication

    Authorization: Basic base64encoded[client_id:client_secret]

According to the OAuth2 spec, this is the preferred method.  It also enables
Authorization Servers that only support basic authentication during the
authorization_code grant.

https://tools.ietf.org/html/rfc6749#section-2.3.1
2017-07-12 23:32:29 -05:00
Kenny 143c8e44df Modify test running script, rewrite some test based on local son 2017-07-12 05:51:00 -07:00
RVKen 25a602bc18 write overall e2e test script 2017-07-10 21:00:58 +02:00
RVKen 98b633a143 add copy-webpack-plugin dependency 2017-07-08 20:56:11 +02:00
Owen Conti 5de1689946 Remove embedded styles from index.html files 2017-07-08 11:34:55 -06:00
Owen Conti 48f11a172a Fixes #2903 - Fix CSS imports so body and html styles are included from .scss files. Update body selector to have a font-family 2017-07-08 11:33:34 -06:00
RVKen ee2f9d0a01 take out bin files from the repo 2017-07-07 10:10:25 +02:00
RVKen 9e8007398a mock api 2017-07-07 09:47:39 +02:00
shockey 346218f0ca Merge branch 'master' into issue-1334 2017-07-06 18:27:00 -07:00
RVKen 170dcece36 remove passing spec params to SwaggerUIBundle
server test json files via webpack-dev-server
2017-07-06 09:51:01 +02:00
RVKen a3249f0d6f Merge branch 'master' into issue-1334
* master: (50 commits)
  update NoErrorsPlugin to NoEmitOnErrorsPlugin
  Undo change to `swagger-client` dependency
  trigger setScheme when a new set of schemes come in
  fix eslint issues
  pin yams version
  update dist
  revert dependencies
  minify bundle css
  migrate webpack to v2.6.1
  #3110 - Fix models down arrow icon in firefox
  Fixes #3299 - export validateNumber and validateInteger for easy reuse and testing. Broke validateParam required check onto multiple lines. Added tests for validateNumber, validateInteger, and validateParam
  Improve README with more information about `urls`
  Rename variable: "selectedName" -> "primaryName"
  "name" -> "urls.primaryName"
  Update selectedIndex when a new URL is loaded
  Use select value to avoid react warning
  Properly added name config Now access it through getConfigs Documented it in README
  Add displayRequestDuration configuration option.
  Fix for #2947 - Display property names for non-object models
  #3256 - Remove unnecessary JSON.stringify call on example values that are already strings
  ...

# Conflicts:
#	dist/swagger-ui-bundle.js
#	dist/swagger-ui-bundle.js.map
#	dist/swagger-ui-standalone-preset.js
#	dist/swagger-ui-standalone-preset.js.map
#	dist/swagger-ui.css
#	dist/swagger-ui.css.map
#	dist/swagger-ui.js
#	dist/swagger-ui.js.map
#	make-webpack-config.js
#	package.json
#	webpack-dist.config.js
#	webpack-hot-dev-server.config.js
2017-06-30 23:24:43 +02:00
RVKen 8324486b27 write mechanism to provide local spec JSON to SwaggerUIBundle 2017-06-30 23:11:34 +02:00
RVKen 94a1997c08 migrate webpack to v2.6.1 2017-06-28 09:43:53 +02:00
RVKen c72140fb28 fix selenium-server-standalone-jar package version 2017-06-23 18:11:19 +02:00
RVKen 57beaada82 replace binary files with npm module 2017-06-23 10:52:48 +02:00
RVKen 575e35dc8c beautify spec json 2017-06-23 10:00:12 +02:00
RVKen e2fbf50c96 write schemeContainer tests 2017-06-23 00:57:53 -07:00
RVKen d218cc8fc6 write informationContainer test 2017-06-21 08:44:14 -07:00
RVKen d53a139e9c write some tests 2017-06-20 01:53:43 -07:00
RVKen c553f4587e gitignore selenium log 2017-06-19 22:44:18 +02:00
RVKen 622ce14195 integrate nightwatch 2017-06-19 22:43:12 +02:00
66 changed files with 3213 additions and 188 deletions
+63 -3
View File
@@ -1,3 +1,63 @@
When reporting an issue, please provide the following details:
- swagger-ui version
- a swagger file reproducing the issue
<!---
Thanks for filing an issue 😄 ! Before you submit, please read the following:
Search open/closed issues before submitting since someone might have asked the same thing before!
Issues on GitHub are only related to problems of Swagger-UI itself. We'll try to offer support
here for your use case, but we can't offer help with projects that use Swagger-UI indirectly,
like Springfox or swagger-node.
Likewise, we can't accept features or bugs in the Swagger/OpenAPI specifications themselves,
or anything that violates the specifications.
-->
<!--- Provide a general summary of the issue in the title above -->
| 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
<!--- If you're describing a bug, please provide an API definition that reproduces your problem -->
<!--- If you have link to a demo repo please link that! -->
<!--- If your spec is large, please put it into a Gist (https://gist.github.com) instead of pasting it here. -->
```yaml
your: "API definition goes here"
```
### Configuration (browser query string, constructor, config.yaml)
<!--- If describing a bug, tell us what your configuration looks like -->
```js
{
"your": { "constructorConfig": "here" }
}
```
`?yourQueryStringConfig=here`
### Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
### Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
### Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
### Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
+2
View File
@@ -6,3 +6,5 @@ npm-debug.log*
.eslintcache
package-lock.json
*.iml
selenium-debug.log
test/e2e/db.json
+54
View File
@@ -0,0 +1,54 @@
## Contributing to Swagger-UI
We love contributions from our community of users! This document explains our guidelines and workflows. Please take care to follow them, as it helps us keep things moving smoothly.
#### Environment setup
0. Install Node.js (4 or newer) and npm (3 or newer).
1. Make a fork of Swagger-UI on GitHub, then clone your fork to your machine.
2. Run `npm install` in your Swagger-UI directory.
3. Run `npm run dev`. `localhost:3200` should open automatically.
4. You're ready to go!
#### Branching model
Feature branches should be prefixed with `ft/`.
Bugfix branches should be prefixed with `bug/`.
Version branches should be prefixed with `v/`.
After the forward slash, include a short description of what you're fixing. For example: `bug/fix-everything-that-was-broken`. For versions, add the version that will be released via the branch, for example: `v/1.2.3`.
If there's an issue filed that you're addressing in your branch, include the issue number directly after the forward slash. For example: `bug/1234-fix-all-the-other-things`.
#### Filing issues
- **Do** include the Swagger-UI build you're using - you can find this by opening your console and checking `window.versions.swaggerUi`
- **Do** include a spec that demonstrates the issue you're experiencing.
- **Do** include screenshots, if needed. GIFs are even better!
- **Do** place code inside of a pre-formatted container by surrounding the code with triple backticks.
- **Don't** open tickets discussing issues with the Swagger/OpenAPI specification itself, or for issues with projects that use Swagger-UI.
- **Don't** open an issue without searching the issue tracker for duplicates first.
#### Committing
- Break your commits into logical atomic units. Well-segmented commits make it _much_ easier for others to step through your changes.
- Limit your subject (first) line to 50 characters (GitHub truncates more than 70).
- Provide a body if you'd like to explain your commit in detail.
- Capitalize the beginning of your subject line, and do not end the subject line with a period.
- Your subject line should complete this sentence: `If applied, this commit will [your subject line].`
- Don't use [magic GitHub words](https://help.github.com/articles/closing-issues-using-keywords/) in your commits to close issues - do that in the pull request for your code instead.
_Adapted from [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/#seven-rules)._
#### Making pull requests
- **Do** summarize your changes in the PR body. If in doubt, write a bullet-point list titled `This PR does the following:`.
- **Do** include references to issues that your PR solves, and use [magic GitHub words](https://help.github.com/articles/closing-issues-using-keywords/) to close those issues automatically when your PR is merged.
- **Do** include tests that cover new or changed functionality.
- **Do** be careful to follow our ESLint style rules. We recommend installing an ESLint plugin if you use a graphical code editor.
- **Do** make sure that tests and the linter are passing by running `npm test` locally, otherwise we can't merge your pull request.
- **Don't** include any changes to files in the `dist/` directory - we update those files only during releases.
- **Don't** mention maintainers in your original PR body - we probably would've seen it anyway, so it just increases the noise in our inboxes. Do feel free to ping maintainers if a week has passed and you've heard nothing from us.
- **Don't** open PRs for custom functionality that only serves a small subset of our users - custom functionality should be implemented outside of our codebase, via a plugin.
+18 -3
View File
@@ -18,11 +18,11 @@ This repo publishes to two different NPM packages:
For the older version of swagger-ui, refer to the [*2.x branch*](https://github.com/swagger-api/swagger-ui/tree/2.x).
## Compatibility
The OpenAPI Specification has undergone 4 revisions since initial creation in 2010. Compatibility between swagger-ui and the OpenAPI Specification is as follows:
The OpenAPI Specification has undergone 5 revisions since initial creation in 2010. Compatibility between swagger-ui and the OpenAPI Specification is as follows:
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
------------------ | ------------ | -------------------------- | -----
3.1.2 | 2017-07-31 | 2.0, 3.0 | [tag v3.1.2](https://github.com/swagger-api/swagger-ui/tree/v3.1.2)
3.1.6 | 2017-08-18 | 2.0, 3.0 | [tag v3.1.6](https://github.com/swagger-api/swagger-ui/tree/v3.1.6)
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
@@ -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.
@@ -97,7 +106,8 @@ To use swagger-ui's bundles, you should take a look at the [source of swagger-ui
#### OAuth2 configuration
You can configure OAuth2 authorization by calling `initOAuth` method with passed configs under the instance of `SwaggerUIBundle`
default `client_id` and `client_secret`, `realm`, an application name `appName`, `scopeSeparator`, `additionalQueryStringParams`.
default `client_id` and `client_secret`, `realm`, an application name `appName`, `scopeSeparator`, `additionalQueryStringParams`,
`useBasicAuthenticationWithAccessCodeGrant`.
Config Name | Description
--- | ---
@@ -107,6 +117,7 @@ realm | realm query parameter (for oauth1) added to `authorizationUrl` and `toke
appName | application name, displayed in authorization popup. MUST be a string
scopeSeparator | scope separator for passing scopes, encoded before calling, default value is a space (encoded value `%20`). MUST be a string
additionalQueryStringParams | Additional query parameters added to `authorizationUrl` and `tokenUrl`. MUST be an object
useBasicAuthenticationWithAccessCodeGrant | Only activated for the `accessCode` flow. During the `authorization_code` request to the `tokenUrl`, pass the [Client Password](https://tools.ietf.org/html/rfc6749#section-2.3.1) using the HTTP Basic Authentication scheme (`Authorization` header with `Basic base64encoded[client_id:client_secret]`). The default is `false`
```
const ui = SwaggerUIBundle({...})
@@ -136,6 +147,7 @@ urls.primaryName | When using `urls`, you can use this subparameter. If the valu
spec | A JSON object describing the OpenAPI Specification. When used, the `url` parameter will not be parsed. This is useful for testing manually-generated specifications without hosting them.
validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
domNode | The HTML DOM element inside which SwaggerUi will put the user interface for swagger. Overrides `dom_id`.
oauth2RedirectUrl | OAuth redirect URL
tagsSorter | Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function (see [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger-UI.
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
@@ -148,6 +160,9 @@ displayRequestDuration | Controls the display of the request duration (in millis
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
deepLinking | If set to `true`, enables dynamic deep linking for tags and operations. [Docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/deep-linking.md)
requestInterceptor | MUST be a function. Function to intercept try-it-out requests. Accepts one argument requestInterceptor(request) and must return the potentially modified request.
responseInterceptor | MUST be a function. Function to intercept try-it-out responses. Accepts one argument responseInterceptor(response) and must return the potentially modified response.
showMutatedRequest | If set to `true` (the default), uses the mutated request returned from a rquestInterceptor to produce the curl command in the UI, otherwise the request before the requestInterceptor was applied is used.
### Plugins
-1
View File
@@ -21,7 +21,6 @@
{
box-sizing: inherit;
}
body {
margin:0;
background: #fafafa;
+4 -4
View File
@@ -11,15 +11,15 @@
<style>
html
{
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after
{
box-sizing: inherit;
box-sizing: inherit;
}
body {
+11 -11
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;AAoyKA;;;;;;AAy+EA;;;;;;;;;;;;;;;;;;;;;;;;;;AA00TA;;;;;;;;;;;;;;AAs8JA;;;;;;;;;AA+5oBA;;;;;AA2lQA;AAm4DA;;;;;;AAo4YA;;;;;;AA0iaA;AAumvBA","sourceRoot":""}
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;AAoyKA;;;;;;AAm/EA;;;;;;;;;;;;;;;;;;;;;;;;;;AAy7TA;;;;;;;;;;;;;;AAs8JA;;;;;;;;;AAwhpBA;;;;;AA41QA;AAm4DA;;;;;;AAo4YA;;;;;;AA8jaA;AAumvBA","sourceRoot":""}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA00CA;;;;;;AAmlFA","sourceRoot":""}
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA21CA;;;;;;AAspFA","sourceRoot":""}
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAwpcA","sourceRoot":""}
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AA2idA","sourceRoot":""}
+9 -5
View File
@@ -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(
+13 -6
View File
@@ -1,6 +1,6 @@
{
"name": "swagger-ui",
"version": "3.1.2",
"version": "3.1.6",
"main": "dist/swagger-ui.js",
"repository": "git@github.com:swagger-api/swagger-ui.git",
"contributors": [
@@ -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",
@@ -43,14 +47,13 @@
"ieee754": "^1.1.8",
"immutable": "^3.x.x",
"js-yaml": "^3.5.5",
"less": "2.7.1",
"lodash": "4.17.2",
"matcher": "^0.1.2",
"memoizee": "0.4.1",
"promise-worker": "^1.1.1",
"prop-types": "^15.5.10",
"react": "^15.4.0",
"react-addons-perf": "0.14.8",
"react-addons-perf": "^15.4.0",
"react-addons-shallow-compare": "0.14.8",
"react-addons-test-utils": "^15.4.0",
"react-collapse": "2.3.1",
@@ -72,7 +75,7 @@
"scroll-to-element": "^2.0.0",
"serialize-error": "2.0.0",
"shallowequal": "0.2.2",
"swagger-client": "3.0.19",
"swagger-client": "3.0.20",
"url-parse": "^1.1.8",
"whatwg-fetch": "0.11.1",
"worker-loader": "^0.7.1",
@@ -91,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",
@@ -101,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",
@@ -112,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",
@@ -122,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",
+2 -3
View File
@@ -15,7 +15,7 @@ export default class ArrayModel extends Component {
}
render(){
let { getComponent, required, schema, depth, expandDepth, name } = this.props
let { getComponent, schema, depth, expandDepth, name } = this.props
let items = schema.get("items")
let title = schema.get("title") || name
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
@@ -31,7 +31,7 @@ export default class ArrayModel extends Component {
return <span className="model">
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent="[...]">
[
<span><Model { ...this.props } schema={ items } required={ false }/></span>
<span><Model { ...this.props } schema={ items } required={ false } depth={ depth + 1 } /></span>
]
{
properties.size ? <span>
@@ -41,7 +41,6 @@ export default class ArrayModel extends Component {
: null
}
</ModelCollapse>
{ required && <span style={{ color: "red" }}>*</span>}
</span>
}
}
@@ -23,7 +23,7 @@ export default class AuthorizationPopup extends React.Component {
<h3>Available authorizations</h3>
<button type="button" className="close-modal" onClick={ this.close }>
<svg width="20" height="20">
<use xlinkHref="#close" />
<use href="#close" xlinkHref="#close" />
</svg>
</button>
</div>
+1 -1
View File
@@ -25,7 +25,7 @@ export default class AuthorizeBtn extends React.Component {
<button className={isAuthorized ? "btn authorize locked" : "btn authorize unlocked"} onClick={ this.onClick }>
<span>Authorize</span>
<svg width="20" height="20">
<use xlinkHref={ isAuthorized ? "#locked" : "#unlocked" } />
<use href={ isAuthorized ? "#locked" : "#unlocked" } xlinkHref={ isAuthorized ? "#locked" : "#unlocked" } />
</svg>
</button>
{ showPopup && <AuthorizationPopup /> }
@@ -24,7 +24,7 @@ export default class AuthorizeOperationBtn extends React.Component {
return (
<button className={isAuthorized ? "authorization__btn locked" : "authorization__btn unlocked"} onClick={ this.onClick }>
<svg width="20" height="20">
<use xlinkHref={ isAuthorized ? "#locked" : "#unlocked" } />
<use href={ isAuthorized ? "#locked" : "#unlocked" } xlinkHref={ isAuthorized ? "#locked" : "#unlocked" } />
</svg>
</button>
+4 -1
View File
@@ -69,7 +69,10 @@ export default class BaseLayout extends React.Component {
<div className="scheme-container">
<Col className="schemes wrapper" mobile={12}>
{ schemes && schemes.size ? (
<Schemes schemes={ schemes } specActions={ specActions } />
<Schemes
currentScheme={specSelectors.operationScheme()}
schemes={ schemes }
specActions={ specActions } />
) : null }
{ securityDefinitions ? (
+8 -3
View File
@@ -29,13 +29,18 @@ Duration.propTypes = {
export default class LiveResponse extends React.Component {
static propTypes = {
response: PropTypes.object.isRequired,
specSelectors: PropTypes.object.isRequired,
pathMethod: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired,
displayRequestDuration: PropTypes.bool.isRequired
displayRequestDuration: PropTypes.bool.isRequired,
getConfigs: PropTypes.func.isRequired
}
render() {
const { request, response, getComponent, displayRequestDuration } = this.props
const { response, getComponent, getConfigs, displayRequestDuration, specSelectors, pathMethod } = this.props
const { showMutatedRequest } = getConfigs()
const curlRequest = showMutatedRequest ? specSelectors.mutatedRequestFor(pathMethod[0], pathMethod[1]) : specSelectors.requestFor(pathMethod[0], pathMethod[1])
const status = response.get("status")
const url = response.get("url")
const headers = response.get("headers").toJS()
@@ -55,7 +60,7 @@ export default class LiveResponse extends React.Component {
return (
<div>
{ request && <Curl request={ request }/> }
{ curlRequest && <Curl request={ curlRequest }/> }
<h4>Server response</h4>
<table className="responses-table">
<thead>
+4 -4
View File
@@ -55,14 +55,14 @@ export default class Model extends Component {
return <ObjectModel
className="object" { ...this.props }
schema={ modelSchema }
name={ name || modelName }
name={ modelName || name }
deprecated={deprecated}
isRef={ isRef!== undefined ? isRef : !!$$ref } />
case "array":
return <ArrayModel
className="array" { ...this.props }
schema={ modelSchema }
name={ name || modelName }
name={ modelName || name }
deprecated={deprecated}
required={ required } />
case "string":
@@ -74,8 +74,8 @@ export default class Model extends Component {
{ ...this.props }
getComponent={ getComponent }
schema={ modelSchema }
name={ name || modelName }
name={ modelName || name }
deprecated={deprecated}
required={ required }/> }
required={ required }/> }
}
}
+1 -1
View File
@@ -24,7 +24,7 @@ export default class Models extends Component {
return <section className={ showModels ? "models is-open" : "models"}>
<h4 onClick={() => layoutActions.show("models", !showModels)}>
<span>Models</span>
<svg className="arrow" width="20" height="20">
<svg width="20" height="20">
<use xlinkHref={showModels ? "#large-arrow-down" : "#large-arrow"} />
</svg>
</h4>
+59 -8
View File
@@ -17,8 +17,10 @@ export default class ObjectModel extends Component {
}
render(){
let { schema, name, isRef, getComponent, depth, ...props } = this.props
let { expandDepth } = this.props
let { schema, name, isRef, getComponent, depth, expandDepth, ...otherProps } = this.props
let { specSelectors } = otherProps
let { isOAS3 } = specSelectors
let description = schema.get("description")
let properties = schema.get("properties")
let additionalProperties = schema.get("additionalProperties")
@@ -30,14 +32,21 @@ export default class ObjectModel extends Component {
const Model = getComponent("Model")
const ModelCollapse = getComponent("ModelCollapse")
const JumpToPathSection = ({ name }) => <span className="model-jump-to-path"><JumpToPath path={`definitions.${name}`} /></span>
const JumpToPathSection = ({ name }) => {
const path = isOAS3 && isOAS3() ? `components.schemas.${name}` : `definitions.${name}`
return <span className="model-jump-to-path"><JumpToPath path={path} /></span>
}
const collapsedContent = (<span>
<span>{ braceOpen }</span>...<span>{ braceClose }</span>
{
isRef ? <JumpToPathSection name={ name }/> : ""
}
</span>)
const anyOf = specSelectors.isOAS3() ? schema.get("anyOf") : null
const oneOf = specSelectors.isOAS3() ? schema.get("oneOf") : null
const not = specSelectors.isOAS3() ? schema.get("not") : null
const titleEl = title && <span className="model-title">
{ isRef && schema.get("$$ref") && <span className="model-hint">{ schema.get("$$ref") }</span> }
<span className="model-title__text">{ title }</span>
@@ -51,7 +60,7 @@ export default class ObjectModel extends Component {
}
<span className="inner-object">
{
<table className="model" style={{ marginLeft: "2em" }}><tbody>
<table className="model"><tbody>
{
!description ? null : <tr style={{ color: "#999", fontStyle: "italic" }}>
<td>description:</td>
@@ -74,7 +83,7 @@ export default class ObjectModel extends Component {
{ key }{ isRequired && <span style={{ color: "red" }}>*</span> }
</td>
<td style={{ verticalAlign: "top" }}>
<Model key={ `object-${name}-${key}_${value}` } { ...props }
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
required={ isRequired }
getComponent={ getComponent }
schema={ value }
@@ -88,13 +97,55 @@ export default class ObjectModel extends Component {
: <tr>
<td>{ "< * >:" }</td>
<td>
<Model { ...props } required={ false }
<Model { ...otherProps } required={ false }
getComponent={ getComponent }
schema={ additionalProperties }
depth={ depth + 1 } />
</td>
</tr>
}
{
!anyOf ? null
: <tr>
<td>{ "anyOf ->" }</td>
<td>
{anyOf.map((schema, k) => {
return <div key={k}><Model { ...otherProps } required={ false }
getComponent={ getComponent }
schema={ schema }
depth={ depth + 1 } /></div>
})}
</td>
</tr>
}
{
!oneOf ? null
: <tr>
<td>{ "oneOf ->" }</td>
<td>
{oneOf.map((schema, k) => {
return <div key={k}><Model { ...otherProps } required={ false }
getComponent={ getComponent }
schema={ schema }
depth={ depth + 1 } /></div>
})}
</td>
</tr>
}
{
!not ? null
: <tr>
<td>{ "not ->" }</td>
<td>
{not.map((schema, k) => {
return <div key={k}><Model { ...otherProps } required={ false }
getComponent={ getComponent }
schema={ schema }
depth={ depth + 1 } /></div>
})}
</td>
</tr>
}
</tbody></table>
}
</span>
@@ -102,4 +153,4 @@ export default class ObjectModel extends Component {
</ModelCollapse>
</span>
}
}
}
+3 -2
View File
@@ -186,7 +186,7 @@ export default class Operation extends PureComponent {
}
</div>
<Collapse isOpened={shown} animated>
<Collapse isOpened={shown}>
<div className="opblock-body">
{ deprecated && <h4 className="opblock-title_normal"> Warning: Deprecated</h4>}
{ description &&
@@ -229,7 +229,7 @@ export default class Operation extends PureComponent {
path={ path }
method={ method }
specActions={ specActions }
operationScheme={ operationScheme } />
currentScheme={ operationScheme } />
</div> : null
}
@@ -263,6 +263,7 @@ export default class Operation extends PureComponent {
request={ request }
tryItOutResponse={ response }
getComponent={ getComponent }
getConfigs={ getConfigs }
specSelectors={ specSelectors }
specActions={ specActions }
produces={ produces }
+19 -1
View File
@@ -66,6 +66,8 @@ export default class Operations extends React.Component {
taggedOps.map( (tagObj, tag) => {
let operations = tagObj.get("operations")
let tagDescription = tagObj.getIn(["tagDetails", "description"], null)
let tagExternalDocsDescription = tagObj.getIn(["tagDetails", "externalDocs", "description"])
let tagExternalDocsUrl = tagObj.getIn(["tagDetails", "externalDocs", "url"])
let isShownKey = ["operations-tag", tag]
let showTag = layoutSelectors.isShown(isShownKey, docExpansion === "full" || docExpansion === "list")
@@ -89,9 +91,25 @@ export default class Operations extends React.Component {
</small>
}
<div>
{ !tagExternalDocsDescription ? null :
<small>
{ tagExternalDocsDescription }
{ tagExternalDocsUrl ? ": " : null }
{ tagExternalDocsUrl ?
<a
href={tagExternalDocsUrl}
onClick={(e) => e.stopPropagation()}
target={"_blank"}
>{tagExternalDocsUrl}</a> : null
}
</small>
}
</div>
<button className="expand-operation" title="Expand operation" onClick={() => layoutActions.show(isShownKey, !showTag)}>
<svg className="arrow" width="20" height="20">
<use xlinkHref={showTag ? "#large-arrow-down" : "#large-arrow"} />
<use href={showTag ? "#large-arrow-down" : "#large-arrow"} xlinkHref={showTag ? "#large-arrow-down" : "#large-arrow"} />
</svg>
</button>
</h4>
+3 -1
View File
@@ -69,7 +69,9 @@ export default class ParamBody extends PureComponent {
let { param, fn:{inferSchema} } = this.props
let schema = inferSchema(param.toJS())
return getSampleSchema(schema, xml)
return getSampleSchema(schema, xml, {
includeWriteOnly: true
})
}
onChange = (value, { isEditBox, isXml }) => {
+8 -2
View File
@@ -58,6 +58,8 @@ export default class ParameterRow extends Component {
render() {
let {param, onChange, getComponent, isExecute, fn, onChangeConsumes, specSelectors, pathMethod} = this.props
let { isOAS3 } = specSelectors
// const onChangeWrapper = (value) => onChange(param, value)
const JsonSchemaForm = getComponent("JsonSchemaForm")
const ParamBody = getComponent("ParamBody")
@@ -80,10 +82,11 @@ export default class ParameterRow extends Component {
let schema = param.get("schema")
let type = isOAS3 && isOAS3() ? param.getIn(["schema", "type"]) : param.get("type")
let isFormData = inType === "formData"
let isFormDataSupported = "FormData" in win
let required = param.get("required")
let itemType = param.getIn(["items", "type"])
let itemType = param.getIn(isOAS3 && isOAS3() ? ["schema", "items", "type"] : ["items", "type"])
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
let value = parameter ? parameter.get("value") : ""
@@ -94,7 +97,10 @@ export default class ParameterRow extends Component {
{ param.get("name") }
{ !required ? null : <span style={{color: "red"}}>&nbsp;*</span> }
</div>
<div className="parameter__type">{ param.get("type") } { itemType && `[${itemType}]` }</div>
<div className="parameter__type">{ type } { itemType && `[${itemType}]` }</div>
<div className="parameter__deprecated">
{ isOAS3 && isOAS3() && param.get("deprecated") ? "deprecated": null }
</div>
<div className="parameter__in">({ param.get("in") })</div>
</td>
+28 -25
View File
@@ -7,11 +7,12 @@ export default class Primitive extends Component {
static propTypes = {
schema: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired,
required: PropTypes.bool
name: PropTypes.string,
depth: PropTypes.number
}
render(){
let { schema, getComponent, required } = this.props
let { schema, getComponent, name, depth } = this.props
if(!schema || !schema.get) {
// don't render if schema isn't correctly formed
@@ -24,32 +25,34 @@ export default class Primitive extends Component {
let enumArray = schema.get("enum")
let description = schema.get("description")
let properties = schema.filter( ( v, key) => ["enum", "type", "format", "description", "$$ref"].indexOf(key) === -1 )
let style = required ? { fontWeight: "bold" } : {}
const Markdown = getComponent("Markdown")
const EnumModel = getComponent("EnumModel")
return <span className="prop">
<span className="prop-type" style={ style }>{ type }</span> { required && <span style={{ color: "red" }}>*</span>}
{ format && <span className="prop-format">(${format})</span>}
{
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
<br />{ key }: { String(v) }</span>)
: null
}
{
!description ? null :
<Markdown source={ description } />
}
{
xml && xml.size ? (<span><br /><span style={ propStyle }>xml:</span>
{
xml.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }><br/>&nbsp;&nbsp;&nbsp;{key}: { String(v) }</span>).toArray()
}
</span>): null
}
{
enumArray && <EnumModel value={ enumArray } getComponent={ getComponent } />
}
return <span className="model">
<span className="prop">
{ name && <span className={`${depth === 1 && "model-title"} prop-name`}>{ name }</span> }
<span className="prop-type">{ type }</span>
{ format && <span className="prop-format">(${format})</span>}
{
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
<br />{ key }: { String(v) }</span>)
: null
}
{
!description ? null :
<Markdown source={ description } />
}
{
xml && xml.size ? (<span><br /><span style={ propStyle }>xml:</span>
{
xml.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }><br/>&nbsp;&nbsp;&nbsp;{key}: { String(v) }</span>).toArray()
}
</span>): null
}
{
enumArray && <EnumModel value={ enumArray } getComponent={ getComponent } />
}
</span>
</span>
}
}
+9 -4
View File
@@ -83,11 +83,16 @@ export default class Response extends React.Component {
if(isOAS3()) {
let oas3SchemaForContentType = response.getIn(["content", this.state.responseContentType, "schema"])
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, { includeReadOnly: true }) : null
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
includeReadOnly: true
}) : null
schema = oas3SchemaForContentType ? inferSchema(oas3SchemaForContentType.toJS()) : null
} else {
schema = inferSchema(response.toJS())
sampleResponse = schema ? getSampleSchema(schema, contentType, { includeReadOnly: true }) : null
sampleResponse = schema ? getSampleSchema(schema, contentType, {
includeReadOnly: true,
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
}) : null
}
let example = getExampleComponent( sampleResponse, examples, HighlightCode )
@@ -122,10 +127,10 @@ export default class Response extends React.Component {
</td>
{specSelectors.isOAS3() ? <td>
{specSelectors.isOAS3() ? <td className="col response-col_links">
{ links ?
links.toSeq().map((link, key) => {
return <OperationLink key={key} name={key} link={ link }/>
return <OperationLink key={key} name={key} link={ link } getComponent={getComponent}/>
})
: <i>No links</i>}
</td> : null}
+7 -3
View File
@@ -16,7 +16,8 @@ export default class Responses extends React.Component {
specActions: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
fn: PropTypes.object.isRequired
fn: PropTypes.object.isRequired,
getConfigs: PropTypes.func.isRequired
}
static defaultProps = {
@@ -29,7 +30,7 @@ export default class Responses extends React.Component {
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val)
render() {
let { responses, request, tryItOutResponse, getComponent, specSelectors, fn, producesValue, displayRequestDuration } = this.props
let { responses, request, tryItOutResponse, getComponent, getConfigs, specSelectors, fn, producesValue, displayRequestDuration } = this.props
let defaultCode = defaultStatusCode( responses )
const ContentType = getComponent( "contentType" )
@@ -57,6 +58,9 @@ export default class Responses extends React.Component {
<LiveResponse request={ request }
response={ tryItOutResponse }
getComponent={ getComponent }
getConfigs={ getConfigs }
specSelectors={ specSelectors }
pathMethod={ this.props.pathMethod }
displayRequestDuration={ displayRequestDuration } />
<h4>Responses</h4>
</div>
@@ -68,7 +72,7 @@ export default class Responses extends React.Component {
<tr className="responses-header">
<td className="col col_header response-col_status">Code</td>
<td className="col col_header response-col_description">Description</td>
{ specSelectors.isOAS3() ? <td className="col col_header response-col_description">Links</td> : null }
{ specSelectors.isOAS3() ? <td className="col col_header response-col_links">Links</td> : null }
</tr>
</thead>
<tbody>
+3 -3
View File
@@ -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())
}
+1 -1
View File
@@ -20,7 +20,7 @@ export default function curl( request ){
if ( request.get("body") ){
if(type === "multipart/form-data" && request.get("method") === "POST") {
for( let [ k,v ] of request.get("body").values()) {
for( let [ k,v ] of request.get("body").entrySeq()) {
curlified.push( "-F" )
if (v instanceof win.File) {
curlified.push( `"${k}=@${v.name};type=${v.type}"` )
+24 -3
View File
@@ -6,6 +6,11 @@ import ApisPreset from "core/presets/apis"
import * as AllPlugins from "core/plugins/all"
import { parseSearch } from "core/utils"
if (process.env.NODE_ENV !== "production") {
const Perf = require("react-addons-perf")
window.Perf = Perf
}
// eslint-disable-next-line no-undef
const { GIT_DIRTY, GIT_COMMIT, PACKAGE_VERSION, HOSTNAME, BUILD_TIME } = buildInfo
@@ -23,6 +28,7 @@ module.exports = function SwaggerUI(opts) {
const defaults = {
// Some general settings, that we floated to the top
dom_id: null,
domNode: null,
spec: {},
url: "",
urls: null,
@@ -36,6 +42,9 @@ module.exports = function SwaggerUI(opts) {
displayOperationId: false,
displayRequestDuration: false,
deepLinking: false,
requestInterceptor: (a => a),
responseInterceptor: (a => a),
showMutatedRequest: true,
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
@@ -58,6 +67,9 @@ module.exports = function SwaggerUI(opts) {
let queryConfig = parseSearch()
const domNode = opts.domNode
delete opts.domNode
const constructorConfig = deepExtend({}, defaults, opts, queryConfig)
const storeConfigs = deepExtend({}, constructorConfig.store, {
@@ -99,6 +111,12 @@ module.exports = function SwaggerUI(opts) {
let localConfig = system.specSelectors.getLocalConfig ? system.specSelectors.getLocalConfig() : {}
let mergedConfig = deepExtend({}, localConfig, constructorConfig, fetchedConfig || {}, queryConfig)
// deep extend mangles domNode, we need to set it manually
if(domNode) {
mergedConfig.domNode = domNode
}
store.setConfigs(mergedConfig)
if (fetchedConfig !== null) {
@@ -112,10 +130,13 @@ module.exports = function SwaggerUI(opts) {
}
}
if(mergedConfig.dom_id) {
system.render(mergedConfig.dom_id, "App")
if(mergedConfig.domNode) {
system.render(mergedConfig.domNode, "App")
} else if(mergedConfig.dom_id) {
let domNode = document.querySelector(mergedConfig.dom_id)
system.render(domNode, "App")
} else {
console.error("Skipped rendering: no `dom_id` was specified")
console.error("Skipped rendering: no `dom_id` or `domNode` was specified")
}
return system
+11 -1
View File
@@ -68,11 +68,21 @@ export default function authorize ( { auth, authActions, errActions, configs, au
// pass action authorizeOauth2 and authentication data through window
// to authorize with oauth2
let callback
if (flow === "implicit") {
callback = authActions.preAuthorizeImplicit
} else if (authConfigs.useBasicAuthenticationWithAccessCodeGrant) {
callback = authActions.authorizeAccessCodeWithBasicAuthentication
} else {
callback = authActions.authorizeAccessCodeWithFormParams
}
win.swaggerUIRedirectOauth2 = {
auth: auth,
state: state,
redirectUrl: redirectUrl,
callback: flow === "implicit" ? authActions.preAuthorizeImplicit : authActions.authorizeAccessCode,
callback: callback,
errCb: errActions.newAuthErr
}
+16 -2
View File
@@ -111,7 +111,7 @@ export const authorizeApplication = ( auth ) => ( { authActions } ) => {
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers })
}
export const authorizeAccessCode = ( { auth, redirectUrl } ) => ( { authActions } ) => {
export const authorizeAccessCodeWithFormParams = ( { auth, redirectUrl } ) => ( { authActions } ) => {
let { schema, name, clientId, clientSecret } = auth
let form = {
grant_type: "authorization_code",
@@ -124,6 +124,21 @@ export const authorizeAccessCode = ( { auth, redirectUrl } ) => ( { authActions
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth})
}
export const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl } ) => ( { authActions } ) => {
let { schema, name, clientId, clientSecret } = auth
let headers = {
Authorization: "Basic " + btoa(clientId + ":" + clientSecret)
}
let form = {
grant_type: "authorization_code",
code: auth.code,
client_id: clientId,
redirect_uri: redirectUrl
}
return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get("tokenUrl"), auth, headers})
}
export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, authSelectors } ) => {
let { body, query={}, headers={}, name, url, auth } = data
let { additionalQueryStringParams } = authSelectors.getConfigs() || {}
@@ -135,7 +150,6 @@ export const authorizeRequest = ( data ) => ( { fn, authActions, errActions, aut
let _headers = Object.assign({
"Accept":"application/json, text/plain, */*",
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/x-www-form-urlencoded"
}, headers)
@@ -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 <span>
<div style={{ padding: "5px 2px" }}>{name}{description ? `: ${description}` : ""}</div>
return <div style={{ marginBottom: "1.5em" }}>
<div style={{ marginBottom: ".5em" }}>
<b><code>{name}</code></b>
{ description ? <Markdown source={description}></Markdown> : null }
</div>
<pre>
Operation `{targetOp}`<br /><br />
Parameters {padString(0, JSON.stringify(parameters, null, 2)) || "{}"}<br />
</pre>
</span>
</div>
}
}
@@ -30,6 +35,7 @@ function padString(n, string) {
}
OperationLink.propTypes = {
getComponent: PropTypes.func.isRequired,
link: ImPropTypes.orderedMap.isRequired,
name: PropTypes.String
}
@@ -16,7 +16,9 @@ const RequestBody = ({ requestBody, getComponent, specSelectors, contentType })
const mediaTypeValue = requestBodyContent.get(contentType)
const sampleSchema = getSampleSchema(mediaTypeValue.get("schema").toJS(), contentType)
const sampleSchema = getSampleSchema(mediaTypeValue.get("schema").toJS(), contentType, {
includeWriteOnly: true
})
return <div>
{ requestBodyDescription &&
@@ -3,7 +3,6 @@ import PropTypes from "prop-types"
import { OAS3ComponentWrapFactory } from "../helpers"
import { Model } from "core/components/model"
class ModelComponent extends Component {
static propTypes = {
schema: PropTypes.object.isRequired,
+34 -25
View File
@@ -9,7 +9,7 @@ const primitives = {
"number": () => 0,
"number_float": () => 0.0,
"integer": () => 0,
"boolean": (schema) => typeof schema.default === "boolean" ? schema.default : true
"boolean": (schema) => typeof schema.default === "boolean" ? schema.default : true
}
const primitive = (schema) => {
@@ -27,7 +27,7 @@ const primitive = (schema) => {
export const sampleFromSchema = (schema, config={}) => {
let { type, example, properties, additionalProperties, items } = objectify(schema)
let { includeReadOnly } = config
let { includeReadOnly, includeWriteOnly } = config
if(example !== undefined)
return example
@@ -46,16 +46,20 @@ export const sampleFromSchema = (schema, config={}) => {
let props = objectify(properties)
let obj = {}
for (var name in props) {
if ( !props[name].readOnly || includeReadOnly ) {
obj[name] = sampleFromSchema(props[name], { includeReadOnly: includeReadOnly })
if ( props[name].readOnly && !includeReadOnly ) {
continue
}
if ( props[name].writeOnly && !includeWriteOnly ) {
continue
}
obj[name] = sampleFromSchema(props[name], config)
}
if ( additionalProperties === true ) {
obj.additionalProp1 = {}
} else if ( additionalProperties ) {
let additionalProps = objectify(additionalProperties)
let additionalPropVal = sampleFromSchema(additionalProps, { includeReadOnly: includeReadOnly })
let additionalPropVal = sampleFromSchema(additionalProps, config)
for (let i = 1; i < 4; i++) {
obj["additionalProp" + i] = additionalPropVal
@@ -65,7 +69,7 @@ export const sampleFromSchema = (schema, config={}) => {
}
if(type === "array") {
return [ sampleFromSchema(items, { includeReadOnly: includeReadOnly }) ]
return [ sampleFromSchema(items, config) ]
}
if(schema["enum"]) {
@@ -96,7 +100,7 @@ export const inferSchema = (thing) => {
export const sampleXmlFromSchema = (schema, config={}) => {
let objectifySchema = objectify(schema)
let { type, properties, additionalProperties, items, example } = objectifySchema
let { includeReadOnly } = config
let { includeReadOnly, includeWriteOnly } = config
let defaultValue = objectifySchema.default
let res = {}
let _attr = {}
@@ -177,27 +181,32 @@ export const sampleXmlFromSchema = (schema, config={}) => {
example = example || {}
for (let propName in props) {
if ( !props[propName].readOnly || includeReadOnly ) {
props[propName].xml = props[propName].xml || {}
if ( props[propName].readOnly && !includeReadOnly ) {
continue
}
if ( props[propName].writeOnly && !includeWriteOnly ) {
continue
}
if (props[propName].xml.attribute) {
let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
let attrExample = props[propName].example
let attrDefault = props[propName].default
_attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault
|| enumAttrVal || primitive(props[propName])
props[propName].xml = props[propName].xml || {}
if (props[propName].xml.attribute) {
let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
let attrExample = props[propName].example
let attrDefault = props[propName].default
_attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault
|| enumAttrVal || primitive(props[propName])
} else {
props[propName].xml.name = props[propName].xml.name || propName
props[propName].example = props[propName].example !== undefined ? props[propName].example : example[propName]
let t = sampleXmlFromSchema(props[propName])
if (Array.isArray(t)) {
res[displayName] = res[displayName].concat(t)
} else {
props[propName].xml.name = props[propName].xml.name || propName
props[propName].example = props[propName].example !== undefined ? props[propName].example : example[propName]
let t = sampleXmlFromSchema(props[propName])
if (Array.isArray(t)) {
res[displayName] = res[displayName].concat(t)
} else {
res[displayName].push(t)
}
res[displayName].push(t)
}
}
}
+20 -1
View File
@@ -12,6 +12,7 @@ export const UPDATE_PARAM = "spec_update_param"
export const VALIDATE_PARAMS = "spec_validate_param"
export const SET_RESPONSE = "spec_set_response"
export const SET_REQUEST = "spec_set_request"
export const SET_MUTATED_REQUEST = "spec_set_mutated_request"
export const LOG_REQUEST = "spec_log_request"
export const CLEAR_RESPONSE = "spec_clear_response"
export const CLEAR_REQUEST = "spec_clear_request"
@@ -177,6 +178,13 @@ export const setRequest = ( path, method, req ) => {
}
}
export const setMutatedRequest = ( path, method, req ) => {
return {
payload: { path, method, req },
type: SET_MUTATED_REQUEST
}
}
// This is for debugging, remove this comment if you depend on this action
export const logRequest = (req) => {
return {
@@ -187,8 +195,9 @@ export const logRequest = (req) => {
// Actually fire the request via fn.execute
// (For debugging) and ease of testing
export const executeRequest = (req) => ({fn, specActions, specSelectors}) => {
export const executeRequest = (req) => ({fn, specActions, specSelectors, getConfigs}) => {
let { pathName, method, operation } = req
let { requestInterceptor, responseInterceptor } = getConfigs()
let op = operation.toJS()
@@ -207,6 +216,16 @@ export const executeRequest = (req) => ({fn, specActions, specSelectors}) => {
specActions.setRequest(req.pathName, req.method, parsedRequest)
let requestInterceptorWrapper = function(r) {
let mutatedRequest = requestInterceptor.apply(this, [r])
let parsedMutatedRequest = Object.assign({}, mutatedRequest)
specActions.setMutatedRequest(req.pathName, req.method, parsedMutatedRequest)
return mutatedRequest
}
req.requestInterceptor = requestInterceptorWrapper
req.responseInterceptor = responseInterceptor
// track duration of request
const startTime = Date.now()
+6 -1
View File
@@ -3,13 +3,14 @@ import { fromJSOrdered, validateParam } from "core/utils"
import win from "../../window"
import {
UPDATE_SPEC,
UPDATE_SPEC,
UPDATE_URL,
UPDATE_JSON,
UPDATE_PARAM,
VALIDATE_PARAMS,
SET_RESPONSE,
SET_REQUEST,
SET_MUTATED_REQUEST,
UPDATE_RESOLVED,
UPDATE_OPERATION_VALUE,
CLEAR_RESPONSE,
@@ -101,6 +102,10 @@ export default {
return state.setIn( [ "requests", path, method ], fromJSOrdered(req))
},
[SET_MUTATED_REQUEST]: (state, { payload: { req, path, method } } ) =>{
return state.setIn( [ "mutatedRequests", path, method ], fromJSOrdered(req))
},
[UPDATE_OPERATION_VALUE]: (state, { payload: { path, value, key } }) => {
let operationPath = ["resolved", "paths", ...path]
if(!state.getIn(operationPath)) {
+9
View File
@@ -237,6 +237,11 @@ export const requests = createSelector(
state => state.get( "requests", Map() )
)
export const mutatedRequests = createSelector(
state,
state => state.get( "mutatedRequests", Map() )
)
export const responseFor = (state, path, method) => {
return responses(state).getIn([path, method], null)
}
@@ -245,6 +250,10 @@ export const requestFor = (state, path, method) => {
return requests(state).getIn([path, method], null)
}
export const mutatedRequestFor = (state, path, method) => {
return mutatedRequests(state).getIn([path, method], null)
}
export const allowTryItOutFor = () => {
// This is just a hook for now.
return true
+1 -2
View File
@@ -58,8 +58,7 @@ export const makeMappedContainer = (getSystem, getStore, memGetComponent, getCom
}
export const render = (getSystem, getStore, getComponent, getComponents, dom) => {
let domNode = document.querySelector(dom)
export const render = (getSystem, getStore, getComponent, getComponents, domNode) => {
let App = (getComponent(getSystem, getStore, getComponents, "App", "root"))
ReactDOM.render(( <App/> ), domNode)
}
+16 -19
View File
@@ -1,21 +1,3 @@
html
{
box-sizing: border-box;
}
*,
*:before,
*:after
{
box-sizing: inherit;
}
body
{
margin: 0;
background: #fafafa;
}
.wrapper
{
width: 100%;
@@ -540,6 +522,22 @@ body
}
}
.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
@@ -699,7 +697,6 @@ body
.renderedMarkdown {
p {
@include text_body();
font-size: 14px;
margin-top: 0px;
margin-bottom: 0px;
}
+6 -2
View File
@@ -227,8 +227,6 @@ span
{
> span.model
{
padding: 0 0 0 10px;
.brace-close
{
padding: 0 0 0 10px;
@@ -236,6 +234,12 @@ span
}
}
.prop-name
{
display: inline-block;
width: 100px;
}
.prop-type
{
color: #55a;
+12 -3
View File
@@ -19,8 +19,8 @@ table
&:first-of-type
{
width: 100px;
padding: 0;
width: 124px;
padding: 0 0 0 2em;
}
}
}
@@ -52,7 +52,8 @@ table
&:first-of-type
{
width: 20%;
max-width: 20%;
min-width: 6em;
padding: 10px 0;
}
}
@@ -138,6 +139,14 @@ table
@include text_code(#888);
}
.parameter__deprecated
{
font-size: 12px;
font-style: italic;
@include text_code(#f00);
}
.table-container
{
+1
View File
@@ -43,6 +43,7 @@
margin: 0;
border: 2px solid #547f00;
border-radius: 4px 0 0 4px;
outline: none;
}
+1
View File
@@ -14,5 +14,6 @@
@import 'information';
@import 'authorize';
@import 'errors';
@include text_body();
@import 'split-pane-mode';
}
+85
View File
@@ -0,0 +1,85 @@
/* eslint-env mocha */
import React from "react"
import { fromJSOrdered } from "core/utils"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import Curl from "components/curl"
import LiveResponse from "components/live-response"
import ResponseBody from "components/response-body"
describe("<LiveResponse/>", function(){
let request = fromJSOrdered({
credentials: "same-origin",
headers: {
accept: "application/xml"
},
url: "http://petstore.swagger.io/v2/pet/1"
})
let mutatedRequest = fromJSOrdered({
credentials: "same-origin",
headers: {
accept: "application/xml",
mutated: "header"
},
url: "http://petstore.swagger.io/v2/pet/1"
})
let requests = {
request: request,
mutatedRequest: mutatedRequest
}
const tests = [
{ showMutatedRequest: true, expected: { request: "mutatedRequest", requestForCalls: 0, mutatedRequestForCalls: 1 } },
{ showMutatedRequest: false, expected: { request: "request", requestForCalls: 1, mutatedRequestForCalls: 0 } }
]
tests.forEach(function(test) {
it("passes " + test.expected.request + " to Curl when showMutatedRequest = " + test.showMutatedRequest, function() {
// Given
let response = fromJSOrdered({
status: 200,
url: "http://petstore.swagger.io/v2/pet/1",
headers: {},
text: "<response/>",
})
let mutatedRequestForSpy = createSpy().andReturn(mutatedRequest)
let requestForSpy = createSpy().andReturn(request)
let components = {
curl: Curl,
responseBody: ResponseBody
}
let props = {
response: response,
specSelectors: {
mutatedRequestFor: mutatedRequestForSpy,
requestFor: requestForSpy,
},
pathMethod: [ "/one", "get" ],
getComponent: (c) => {
return components[c]
},
displayRequestDuration: true,
getConfigs: () => ({ showMutatedRequest: test.showMutatedRequest })
}
// When
let wrapper = shallow(<LiveResponse {...props}/>)
// Then
expect(mutatedRequestForSpy.calls.length).toEqual(test.expected.mutatedRequestForCalls)
expect(requestForSpy.calls.length).toEqual(test.expected.requestForCalls)
const curl = wrapper.find(Curl)
expect(curl.length).toEqual(1)
expect(curl.props().request).toBe(requests[test.expected.request])
})
})
})
+38 -7
View File
@@ -7,35 +7,66 @@ import { fromJS } from "immutable"
import Schemes from "components/schemes"
describe("<Schemes/>", 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(<Schemes {...props}/>)
// 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(<Schemes {...props}/>)
// 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)
})
})
+8 -8
View File
@@ -132,10 +132,10 @@ describe("curlify", function() {
url: "http://example.com",
method: "POST",
headers: { "content-type": "multipart/form-data" },
body: [
["id", "123"],
["name", "Sahar"]
]
body: {
id: "123",
name: "Sahar"
}
}
let curlified = curl(Im.fromJS(req))
@@ -152,10 +152,10 @@ describe("curlify", function() {
url: "http://example.com",
method: "POST",
headers: { "content-type": "multipart/form-data" },
body: [
["id", "123"],
["file", file]
]
body: {
id: "123",
file
}
}
let curlified = curl(Im.fromJS(req))
+163 -1
View File
@@ -1,6 +1,105 @@
import { createXMLExample } from "corePlugins/samples/fn"
import { createXMLExample, sampleFromSchema } from "corePlugins/samples/fn"
import expect from "expect"
describe("sampleFromSchema", function() {
it("returns object with no readonly fields for parameter", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
readOnlyDog: {
readOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0
}
expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected)
})
it("returns object with readonly fields for parameter, with includeReadOnly", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
readOnlyDog: {
readOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0,
readOnlyDog: "string"
}
expect(sampleFromSchema(definition, { includeReadOnly: true })).toEqual(expected)
})
it("returns object without writeonly fields for parameter", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
writeOnlyDog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0
}
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns object with writeonly fields for parameter, with includeWriteOnly", function () {
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
writeOnlyDog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
var expected = {
id: 0,
writeOnlyDog: "string"
}
expect(sampleFromSchema(definition, { includeWriteOnly: true })).toEqual(expected)
})
})
describe("createXMLExample", function () {
var sut = createXMLExample
@@ -554,6 +653,69 @@ describe("createXMLExample", function () {
expect(sut(definition, { includeReadOnly: false })).toEqual(expected)
})
it("returns object with readonly fields for parameter, with includeReadOnly", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n\t<dog>string</dog>\n</animals>"
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
dog: {
readOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
expect(sut(definition, { includeReadOnly: true })).toEqual(expected)
})
it("returns object without writeonly fields for parameter", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n</animals>"
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
dog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
expect(sut(definition)).toEqual(expected)
})
it("returns object with writeonly fields for parameter, with includeWriteOnly", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<id>0</id>\n\t<dog>string</dog>\n</animals>"
var definition = {
type: "object",
properties: {
id: {
type: "integer"
},
dog: {
writeOnly: true,
type: "string"
}
},
xml: {
name: "animals"
}
}
expect(sut(definition, { includeWriteOnly: true })).toEqual(expected)
})
it("returns object with passed property as attribute", function () {
var expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals id=\"0\">\n\t<dog>string</dog>\n</animals>"
var definition = {
+48
View File
@@ -93,6 +93,54 @@ describe("spec plugin - actions", function(){
})
})
it("should pass requestInterceptor/responseInterceptor to fn.execute", function(){
// Given
let configs = {
requestInterceptor: createSpy(),
responseInterceptor: createSpy()
}
const system = {
fn: {
buildRequest: createSpy(),
execute: createSpy().andReturn(Promise.resolve())
},
specActions: {
executeRequest: createSpy(),
setMutatedRequest: createSpy(),
setRequest: createSpy()
},
specSelectors: {
spec: () => fromJS({}),
parameterValues: () => fromJS({}),
contentTypeValues: () => fromJS({}),
url: () => fromJS({})
},
getConfigs: () => configs
}
// When
let executeFn = executeRequest({
pathName: "/one",
method: "GET",
operation: fromJS({operationId: "getOne"})
})
let res = executeFn(system)
// Then
expect(system.fn.execute.calls.length).toEqual(1)
expect(system.fn.execute.calls[0].arguments[0]).toIncludeKey("requestInterceptor")
expect(system.fn.execute.calls[0].arguments[0]).toInclude({
responseInterceptor: configs.responseInterceptor
})
expect(system.specActions.setMutatedRequest.calls.length).toEqual(0)
expect(system.specActions.setRequest.calls.length).toEqual(1)
let wrappedRequestInterceptor = system.fn.execute.calls[0].arguments[0].requestInterceptor
wrappedRequestInterceptor(system.fn.execute.calls[0].arguments[0])
expect(configs.requestInterceptor.calls.length).toEqual(1)
expect(system.specActions.setMutatedRequest.calls.length).toEqual(1)
expect(system.specActions.setRequest.calls.length).toEqual(1)
})
})
xit("should call specActions.setResponse, when fn.execute resolves", function(){
+130
View File
@@ -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"
}
]
}
+63
View File
@@ -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"
}
}
}
}
+505
View File
@@ -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"
},
}
}
}
}
@@ -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()
})
})
+79
View File
@@ -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()
})
})
+172
View File
@@ -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()
})
})
+113
View File
@@ -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()
})
})
+94
View File
@@ -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()
})
})
+52
View File
@@ -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()
})
})
+52
View File
@@ -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()
})
})
})
File diff suppressed because it is too large Load Diff
+5
View File
@@ -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