Skip to content
This repository has been archived by the owner on Jun 18, 2019. It is now read-only.

Copy shares with Electron's Clipboard API #34

Merged
merged 3 commits into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 6 additions & 25 deletions src/components/CopyButton.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
const {clipboard} = require('electron');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { clipboard } from 'electron'; for consistency.

import PropTypes from 'prop-types';
import Button from './Button';

Expand All @@ -16,23 +17,11 @@ export default class CopyButton extends Component {
}

handleClicked() {
let successful;
this.copyEl.select();
this.copyEl.setSelectionRange(0, this.copyEl.value.length);
clipboard.writeText(this.props.targetText);

try {
successful = document.execCommand('copy');
} catch (e) {
successful = false;
}

if (successful) {
this.setState({ copied: 'successful' });
if (this.props.onCopied) {
this.props.onCopied();
}
} else {
this.setState({ copied: 'error' });
this.setState({ copied: 'successful' });
if (this.props.onCopied) {
this.props.onCopied();
}

window.setTimeout(() => this.setState({ copied: null }), 5000);
Expand All @@ -45,26 +34,18 @@ export default class CopyButton extends Component {

if (copied === 'successful') {
copyText = 'Copied';
} else if (copied === 'error') {
copyText = 'Copy failed';
} else {
copyText = this.props.buttonText || 'Copy';
}

return (
<Button type="default"
className="copy"
icon="clipboard"
onClick={this.handleClicked.bind(this)}
{...this.props}>
{copyText}
{/* hidden input for copy to clipboard functionality */}
<input type="text"
style={ { position: 'absolute', top: '-10000px', left: '-10000px' } }
readOnly
ref={(el) => (this.copyEl = el)}
value={this.props.targetText} />
</Button>

);
}
}
2 changes: 1 addition & 1 deletion src/components/ShareRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default class ShareRow extends Component {
}

return (
<div className="share-row" key={share}>
<div className="share-row" key={share} id={`share-${index}`}>
<div className="share-cell share-value">
{`Share #${index}`}
<span className="share-status">
Expand Down
21 changes: 17 additions & 4 deletions test/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const appPath = path.join(__dirname, '..');

describe('main window', function spec() {
this.timeout(5000);
let shares; // Store the generated shares for recovery

let shares = []; // Store the generated shares for recovery
const quorum = 2;
const numShares = 3;
const secret = 'test secret';
Expand Down Expand Up @@ -49,9 +50,12 @@ describe('main window', function spec() {
expect(shareEls.value).to.have.length(3);
});

it('should find and store the share values', async () => {
// Depends on implementation of the copy button, less than ideal.
shares = await app.client.getAttribute('input[readonly]', 'value');
it('should copy the share values to the clipboard and store them', async () => {
for (let i = 0; i < quorum; i++) {
await app.client.element(`#share-${i+1} .copy`).click();
const share = await app.electron.clipboard.readText();
shares.push(share);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍 So clean!

});

it('should go back to the home screen', async () => {
Expand Down Expand Up @@ -89,5 +93,14 @@ describe('main window', function spec() {
await app.client.waitForVisible('.secret-view');
const foundSecret = await app.client.getAttribute('.secret-view', 'value');
expect(foundSecret).to.be.eql(secret);
await app.client.element('.btn*=Hide').click();
});

it('should be able to copy the recovered secret', async () => {
// Make sure the clipboard is clear before copying
await app.electron.clipboard.clear();
await app.client.element('.copy').click();
const copiedSecret = await app.electron.clipboard.readText();
expect(copiedSecret).to.be.eql(secret);
});
});