Skip to content

Commit

Permalink
Integrates export import feature (#10)
Browse files Browse the repository at this point in the history
* Add import export feature
* Use dialog to provide feedback
* Update dependencies
* Add tests for export import feature
* Update README
* Bump version

Co-authored-by: Ken Siprell <kensiprell@users.noreply.github.com>
  • Loading branch information
Albert Beade and kensiprell committed Feb 25, 2020
1 parent 89ea260 commit 647d7df
Show file tree
Hide file tree
Showing 32 changed files with 491 additions and 145 deletions.
79 changes: 40 additions & 39 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
{
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module"
},
"env": {
"es6": true,
"browser": true,
"cypress/globals": true,
"jquery": true,
"webextensions": true
},
"plugins": [
"chai-friendly",
"cypress",
"promise",
"standard"
],
"extends": [
"standard",
"standard-preact"
],
"settings": {
"react": {
"pragma": "h"
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module"
},
"env": {
"es6": true,
"browser": true,
"cypress/globals": true,
"jquery": true,
"webextensions": true
},
"plugins": [
"chai-friendly",
"cypress",
"promise",
"standard"
],
"extends": [
"standard",
"standard-preact"
],
"settings": {
"react": {
"pragma": "h"
}
},
"globals": {
"document": true,
"navigator": false,
"spyOnEvent": true,
"window": true
},
"rules": {
"chai-friendly/no-unused-expressions": 2,
"no-unused-expressions": 0,
"no-useless-escape": "off",
"object-curly-spacing": "off",
"quote-props": "off",
"quotes": "off",
"standard/no-callback-literal": "off"
}
},
"globals": {
"document": true,
"navigator": false,
"spyOnEvent": true,
"window": true
},
"rules": {
"chai-friendly/no-unused-expressions": 2,
"no-unused-expressions": 0,
"no-useless-escape": "off",
"object-curly-spacing": "off",
"quotes": "off",
"standard/no-callback-literal": "off"
}
}
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Look for the blue WebSocket icon in the toolbar after installation:

The screenshot below shows the "Client" section in use with a pretty-printed message modal on top. The message is formatted as a JavaScript Object with a single color for keys and different colors for values based on the type: boolean, null, number, and string.

![screenshot_1](screenshots/firefox/screenshot_1.png?raw=true)
![screenshot_1](screenshots/chrome/screenshot_1.png?raw=true)

### Options Section

Expand All @@ -46,25 +46,31 @@ The screenshot below shows the "Preferences" section. It allows you to control t
* Allow or prevent saving message bodies with invalid JSON in the Options section
* Allow or prevent using message bodies with invalid JSON Client section

![screenshot_2](screenshots/firefox/screenshot_2.png?raw=true)
![screenshot_2](screenshots/chrome/screenshot_2.png?raw=true)

#### Server URLs

The screenshot below shows the "Server URLs" section. It allows you to save URLs that you can use later in the Client section by selecting them from a dropdown menu. You can create, edit, and delete URLs. When creating or editing a URL you will receive a warning if the URL does not begin with `ws://` or `wss://` or if the URL contains spaces.

![screenshot_3](screenshots/firefox/screenshot_3.png?raw=true)
![screenshot_3](screenshots/chrome/screenshot_3.png?raw=true)

#### Server Protocols

The screenshot below shows the "Server Protocols" section. It allows you to save URLs that you can use later in the Client section by selecting them from a dropdown menu. You can create, edit, and delete protocols.

![screenshot_4](screenshots/firefox/screenshot_4.png?raw=true)
![screenshot_4](screenshots/chrome/screenshot_4.png?raw=true)

#### Messages

The screenshot below shows the "Messages" section. It allows you to save message names and bodies that you can use later in the Client section by selecting the message name from a dropdown menu. You can create, edit, and delete messages. You will receive a warning if the message body is not valid JSON. Note the toggle switch under the message body textarea. Use it to change the JSON formatting from single line to multi-line and vice versa.

![screenshot_5](screenshots/firefox/screenshot_5.png?raw=true)
![screenshot_5](screenshots/chrome/screenshot_5.png?raw=true)

#### Configuration Export and Import

The screenshot below shows the "Configuration Export and Import" section. It allows you to export and import the whole plugin configuration including stored preferences, server URLs, server protocols and messages. This way you can easily backup and share your configuration.

![screenshot_5](screenshots/chrome/screenshot_6.png?raw=true)

## Manual Installation

Expand Down Expand Up @@ -111,6 +117,11 @@ The JavaScript is written in ES6.

[Cypress](https://www.cypress.io) does all the testing.

To run the tests:

* Start [Serve](https://github.com/zeit/serve) using `npx serve` on the project root folder
* Execute `npx cypress open` in the tests folder at `src/test`

## Inspiration

This extension was inspired by [Simple-WebSocket-Client](https://github.com/hakobera/Simple-WebSocket-Client).
Expand Down
74 changes: 37 additions & 37 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"lint": "eslint -c .eslintrc.json src/**/*.js",
"cypress": "cypress open --project ./src/test",
"serve": "serve -l 3000",
"test": "concurrently --kill-others \"npm:build:firefox\" \"npm:serve\" \"npm:cypress\"",
"test": "concurrently --kill-others \"npm:build:chrome\" \"npm:serve\" \"npm:cypress\"",
"zip:chrome": "npm run build:chrome:production && mkdirp ./dist && zip -jr dist/chrome.zip build/production/chrome/*",
"zip:firefox": "npm run build:firefox:production && mkdirp ./dist && zip -jr dist/firefox.zip build/production/firefox/*",
"zip:all": "npm run zip:chrome && npm run zip:firefox"
Expand All @@ -37,48 +37,48 @@
"@fortawesome/fontawesome": "1.1.8",
"@fortawesome/fontawesome-free-regular": "5.0.13",
"@fortawesome/fontawesome-free-solid": "5.0.13",
"bootstrap": "4.3.1",
"jquery": "3.4.0",
"popper.js": "1.15.0"
"bootstrap": "4.4.1",
"jquery": "3.4.1",
"popper.js": "1.16.1"
},
"devDependencies": {
"@babel/core": "7.4.3",
"@babel/plugin-proposal-object-rest-spread": "7.4.3",
"@babel/preset-env": "7.4.3",
"@cypress/webpack-preprocessor": "4.0.3",
"@types/chrome": "0.0.83",
"@types/node": "11.13.6",
"autoprefixer": "9.5.1",
"babel-loader": "8.0.5",
"concurrently": "4.1.0",
"copy-webpack-plugin": "5.0.2",
"css-loader": "2.1.1",
"cypress": "3.2.0",
"eslint": "5.16.0",
"eslint-config-standard": "12.0.0",
"@babel/core": "7.8.4",
"@babel/plugin-proposal-object-rest-spread": "7.8.3",
"@babel/preset-env": "7.8.4",
"@cypress/webpack-preprocessor": "4.1.2",
"@types/chrome": "0.0.96",
"@types/node": "13.7.4",
"autoprefixer": "9.7.4",
"babel-loader": "8.0.6",
"concurrently": "5.1.0",
"copy-webpack-plugin": "^5.1.1",
"css-loader": "3.4.2",
"cypress": "4.0.2",
"eslint": "6.8.0",
"eslint-config-standard": "14.1.0",
"eslint-config-standard-preact": "1.1.6",
"eslint-plugin-chai-friendly": "0.4.1",
"eslint-plugin-cypress": "2.2.1",
"eslint-plugin-import": "2.17.2",
"eslint-plugin-node": "8.0.1",
"eslint-plugin-promise": "4.1.1",
"eslint-plugin-standard": "4.0.0",
"file-loader": "3.0.1",
"eslint-plugin-chai-friendly": "0.5.0",
"eslint-plugin-cypress": "2.10.3",
"eslint-plugin-import": "2.20.1",
"eslint-plugin-node": "11.0.0",
"eslint-plugin-promise": "4.2.1",
"eslint-plugin-standard": "4.0.1",
"file-loader": "5.1.0",
"generate-json-webpack-plugin": "0.3.1",
"html-loader": "0.5.5",
"less": "3.9.0",
"less-loader": "4.1.0",
"mkdirp": "0.5.1",
"node-sass": "4.11.0",
"less": "3.11.1",
"less-loader": "5.0.0",
"mkdirp": "1.0.3",
"node-sass": "^4.13.1",
"postcss-loader": "3.0.0",
"precss": "4.0.0",
"rimraf": "2.6.3",
"sass-loader": "7.1.0",
"serve": "11.0.0",
"style-loader": "0.23.1",
"url-loader": "1.1.2",
"webpack": "4.30.0",
"webpack-cli": "3.3.1",
"webpack-merge": "4.2.1"
"rimraf": "3.0.2",
"sass-loader": "8.0.2",
"serve": "11.3.0",
"style-loader": "1.1.3",
"url-loader": "3.0.0",
"webpack": "4.41.6",
"webpack-cli": "3.3.11",
"webpack-merge": "4.2.2"
}
}
Binary file modified screenshots/chrome/screenshot_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/chrome/screenshot_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/chrome/screenshot_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/chrome/screenshot_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/chrome/screenshot_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/chrome/screenshot_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/firefox/screenshot_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/firefox/screenshot_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/firefox/screenshot_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/firefox/screenshot_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/firefox/screenshot_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/firefox/screenshot_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions serve.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"public": "build/development/firefox"
}
"public": "build/development/chrome"
}
2 changes: 1 addition & 1 deletion src/main/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ It does not impact the WebSocket client itself.
*/

function extensionUrl () {
let isFirefox = typeof InstallTrigger !== 'undefined'
const isFirefox = typeof InstallTrigger !== 'undefined'
let extensionUrl = 'chrome-extension://' + location.host + '/index.html'
if (isFirefox) {
extensionUrl = 'moz-extension://' + location.host + '/index.html'
Expand Down
99 changes: 98 additions & 1 deletion src/main/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ <h5 class="bwc-margin-top">
type="text"
placeholder="Display Name"/>
<label id="optionsMessageTextareaLabel" for="optionsMessageTextarea">
The message body does not appear in the "Saved Messages" table or Client drop-down menu:
The message body does not appear in the "Saved Messages" table or Client drop-down
menu:
</label>
<textarea id="optionsMessageTextarea"
class="form-control"
Expand Down Expand Up @@ -352,6 +353,72 @@ <h5 class="bwc-margin-top">
</div>
</div>
</div>

<!--EXPORT/IMPORT-->

<div class="card">
<div id="optionsExportImportHeading" class="card-header" role="tab">
<h5 class="mb-0">
<a id="optionsExportImportAnchor"
class="bwc-accordion-anchor"
data-toggle="collapse"
href="#optionsExportImport"
aria-expanded="false"
aria-controls="optionsExportImport">
Configuration Export and Import
<i class="fa fa-chevron-down bwc-accordion-heading-icon float-right"
aria-hidden="true"></i>
</a>
</h5>
</div>
<div id="optionsExportImport"
class="collapse"
role="tabpanel"
aria-labelledby="optionsExportImportHeading"
data-parent="#options">
<div class="card-body">
<h5>
Export and Import
</h5>
<p>
You can export and import the extension's configuration (preferences, URLs, protocols, and
messages).
</p>
<h5 class="bwc-margin-top">
Export Configuration
</h5>
<p>
Exports the current configuration. You will be prompted to choose a file
name and location. It defaults to your downloads directory and a filename of
<code>wsclient.json</code>.
</p>
<button id="optionsExportImportExportButton" class="btn btn-primary">
Export Configuration
</button>
<h5 class="bwc-margin-top">
Import Configuration
</h5>
<p>
Imports a previously exported configuration.
</p>
<p id="optionsExportImportImportWarning" class="alert alert-warning rounded">
<b><em>All</em></b> of your current settings will be overridden by the imported configuration.
</p>
<form>
<div class="form-group">
<label class="btn btn-primary">
Choose Configuration File
<input id="optionsExportImportFileInput" type="file" accept=".json" hidden>
</label>
</div>
</form>
<p id="optionsExportImportFileName"></p>
<button id="optionsExportImportImportButton" class="btn btn-danger" disabled="disabled">
Import Configuration File
</button>
</div>
</div>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -558,6 +625,36 @@ <h5 id="jsonModalTitle" class="modal-title">
</div>
</div>

<!--IMPORT MODAL-->

<div class="modal fade" id="importModal" tabindex="-1" role="dialog" aria-labelledby="importModal"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="importModalTitle">
Confirm Import
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p id="importModalBody"></p>
<p id="importModalDescription" class="hide"></p>
</div>
<div class="modal-footer">
<button id="importModalContinueButton" type="button" class="btn btn-danger" data-target="">
Import
</button>
<button id="importModalCancelButton" type="button" class="btn btn-secondary" data-dismiss="modal">
Cancel
</button>
</div>
</div>
</div>
</div>

<script src="index.js"></script>
<script src="styles.js"></script>
</body>
Expand Down
Loading

0 comments on commit 647d7df

Please sign in to comment.