Compare commits

..
163 Commits
Author SHA1 Message Date
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
60 changed files with 3021 additions and 181 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.
+15 -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.5 | 2017-08-11 | 2.0, 3.0 | [tag v3.1.5](https://github.com/swagger-api/swagger-ui/tree/v3.1.5)
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.
-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;;;;;;;;;;;;;;;;;;;;;;;;;;AAs6TA;;;;;;;;;;;;;;AAs8JA;;;;;;;;;AAogpBA;;;;;AAk1QA;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;;;;;;AA0/cA","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.5",
"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 ? (
+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>
}
}
}
+2 -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
}
+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}
+1 -1
View File
@@ -68,7 +68,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}"` )
+18 -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,
@@ -99,6 +105,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(opts.domNode) {
mergedConfig.domNode = opts.domNode
}
store.setConfigs(mergedConfig)
if (fetchedConfig !== null) {
@@ -112,10 +124,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)
}
}
}
+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';
}
+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 = {
+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