diff --git a/lib/gui/app/components/flash-results/flash-results.tsx b/lib/gui/app/components/flash-results/flash-results.tsx index 2eaaee95..dad0d822 100644 --- a/lib/gui/app/components/flash-results/flash-results.tsx +++ b/lib/gui/app/components/flash-results/flash-results.tsx @@ -127,12 +127,12 @@ export function FlashResults({ }; } & FlexProps) { const [showErrorsInfo, setShowErrorsInfo] = React.useState(false); - const allFailed = results.devices.successful === 0; + const allFailed = !skip && results.devices.successful === 0; const someFailed = results.devices.failed !== 0 || errors.length !== 0; const effectiveSpeed = _.round( bytesToMegabytes( results.sourceMetadata.size / - (results.bytesWritten / results.averageFlashingSpeed), + (results.sourceMetadata.blockmappedSize / results.averageFlashingSpeed), ), 1, ); @@ -155,7 +155,7 @@ export function FlashResults({ {middleEllipsis(image, 24)} - Flash Complete! + Flash {allFailed ? 'Failed' : 'Complete'}! {skip ? Validation has been skipped : null} diff --git a/lib/gui/app/components/progress-button/progress-button.tsx b/lib/gui/app/components/progress-button/progress-button.tsx index 2e501837..43fe70e0 100644 --- a/lib/gui/app/components/progress-button/progress-button.tsx +++ b/lib/gui/app/components/progress-button/progress-button.tsx @@ -23,7 +23,7 @@ import { StepButton } from '../../styled-components'; const FlashProgressBar = styled(ProgressBar)` > div { - width: 220px; + width: 100%; height: 12px; color: white !important; text-shadow: none !important; @@ -33,7 +33,7 @@ const FlashProgressBar = styled(ProgressBar)` } } - width: 220px; + width: 100%; height: 12px; margin-bottom: 6px; border-radius: 14px; diff --git a/lib/gui/app/modules/image-writer.ts b/lib/gui/app/modules/image-writer.ts index c8034267..09a78e2d 100644 --- a/lib/gui/app/modules/image-writer.ts +++ b/lib/gui/app/modules/image-writer.ts @@ -17,7 +17,7 @@ import { Drive as DrivelistDrive } from 'drivelist'; import * as electron from 'electron'; import * as sdk from 'etcher-sdk'; -import * as _ from 'lodash'; +import { Dictionary } from 'lodash'; import * as ipc from 'node-ipc'; import * as os from 'os'; import * as path from 'path'; @@ -133,6 +133,14 @@ function writerEnv() { interface FlashResults { skip?: boolean; cancelled?: boolean; + results?: { + bytesWritten: number; + devices: { + failed: number; + successful: number; + }; + errors: Error[]; + }; } async function performWrite( @@ -177,10 +185,12 @@ async function performWrite( }); ipc.server.on('done', (event) => { - event.results.errors = _.map(event.results.errors, (data) => { - return errors.fromJSON(data); - }); - _.merge(flashResults, event); + event.results.errors = event.results.errors.map( + (data: Dictionary & { message: string }) => { + return errors.fromJSON(data); + }, + ); + flashResults.results = event.results; }); ipc.server.on('abort', () => { @@ -209,7 +219,7 @@ async function performWrite( const argv = writerArgv(); ipc.server.on('start', async () => { - console.log(`Elevating command: ${_.join(argv, ' ')}`); + console.log(`Elevating command: ${argv.join(' ')}`); const env = writerEnv(); try { const results = await permissions.elevateCommand(argv, { @@ -231,11 +241,11 @@ async function performWrite( } console.log('Flash results', flashResults); - // This likely means the child died halfway through + // The flash wasn't cancelled and we didn't get a 'done' event if ( !flashResults.cancelled && !flashResults.skip && - !_.get(flashResults, ['results', 'bytesWritten']) + flashResults.results === undefined ) { reject( errors.createUserError({ diff --git a/lib/gui/app/pages/main/Flash.tsx b/lib/gui/app/pages/main/Flash.tsx index 70affdaf..544878d2 100644 --- a/lib/gui/app/pages/main/Flash.tsx +++ b/lib/gui/app/pages/main/Flash.tsx @@ -59,6 +59,27 @@ const getErrorMessageFromCode = (errorCode: string) => { return ''; }; +function notifySuccess( + iconPath: string, + basename: string, + drives: any, + devices: { successful: number; failed: number }, +) { + notification.send( + 'Flash complete!', + messages.info.flashComplete(basename, drives, devices), + iconPath, + ); +} + +function notifyFailure(iconPath: string, basename: string, drives: any) { + notification.send( + 'Oops! Looks like the flash failed.', + messages.error.flashFailure(basename, drives), + iconPath, + ); +} + async function flashImageToDrive( isFlashing: boolean, goToSuccess: () => void, @@ -84,20 +105,20 @@ async function flashImageToDrive( if (!flashState.wasLastFlashCancelled()) { const { results = { devices: { successful: 0, failed: 0 } }, + skip, + cancelled, } = flashState.getFlashResults(); - notification.send( - 'Flash complete!', - messages.info.flashComplete(basename, drives as any, results.devices), - iconPath, - ); + if (!skip && !cancelled) { + if (results.devices.successful > 0) { + notifySuccess(iconPath, basename, drives, results.devices); + } else { + notifyFailure(iconPath, basename, drives); + } + } goToSuccess(); } } catch (error) { - notification.send( - 'Oops! Looks like the flash failed.', - messages.error.flashFailure(path.basename(image.path), drives), - iconPath, - ); + notifyFailure(iconPath, basename, drives); let errorMessage = getErrorMessageFromCode(error.code); if (!errorMessage) { error.image = basename; @@ -135,6 +156,7 @@ interface FlashStepProps { failed: number; speed?: number; eta?: number; + width: string; } export interface DriveWithWarnings extends constraints.DrivelistDrive { @@ -241,6 +263,7 @@ export class FlashStep extends React.PureComponent< this.setState({ current: 'success' })} shouldFlashStepBeDisabled={shouldFlashStepBeDisabled} isFlashing={this.state.isFlashing} diff --git a/lib/gui/app/styled-components.tsx b/lib/gui/app/styled-components.tsx index 79578718..3bd78c1a 100644 --- a/lib/gui/app/styled-components.tsx +++ b/lib/gui/app/styled-components.tsx @@ -149,7 +149,7 @@ export const Modal = styled(({ style, children, ...props }) => { })` > div { padding: 0; - height: 100%; + height: 99%; > div:first-child { height: 81%; diff --git a/lib/gui/app/theme.ts b/lib/gui/app/theme.ts index ee1e27ad..aff21086 100644 --- a/lib/gui/app/theme.ts +++ b/lib/gui/app/theme.ts @@ -100,6 +100,7 @@ export const theme = _.merge({}, Theme, { font-size: 16px; && { + width: 200px; height: 48px; } diff --git a/lib/gui/etcher.ts b/lib/gui/etcher.ts index 02657539..c14f0ece 100644 --- a/lib/gui/etcher.ts +++ b/lib/gui/etcher.ts @@ -133,7 +133,7 @@ async function createMainWindow() { width, height, frame: !fullscreen, - useContentSize: false, + useContentSize: true, show: false, resizable: false, maximizable: false, diff --git a/lib/gui/modules/child-writer.ts b/lib/gui/modules/child-writer.ts index d3939683..713151ba 100644 --- a/lib/gui/modules/child-writer.ts +++ b/lib/gui/modules/child-writer.ts @@ -15,12 +15,23 @@ */ import { Drive as DrivelistDrive } from 'drivelist'; -import * as sdk from 'etcher-sdk'; +import { + BlockDevice, + File, + Http, + Metadata, + SourceDestination, +} from 'etcher-sdk/build/source-destination'; +import { + MultiDestinationProgress, + OnProgressFunction, + OnFailFunction, + decompressThenFlash, +} from 'etcher-sdk/build/multi-write'; import { cleanupTmpFiles } from 'etcher-sdk/build/tmp'; import * as ipc from 'node-ipc'; import { totalmem } from 'os'; -import { BlockDevice, File, Http } from 'etcher-sdk/build/source-destination'; import { toJSON } from '../../shared/errors'; import { GENERAL_ERROR, SUCCESS } from '../../shared/exit-codes'; import { delay } from '../../shared/utils'; @@ -85,7 +96,7 @@ export interface WriteResult { successful: number; }; errors: FlashError[]; - sourceMetadata?: sdk.sourceDestination.Metadata; + sourceMetadata?: Metadata; } export interface FlashResults extends WriteResult { @@ -112,19 +123,15 @@ async function writeAndValidate({ onProgress, onFail, }: { - source: sdk.sourceDestination.SourceDestination; - destinations: sdk.sourceDestination.BlockDevice[]; + source: SourceDestination; + destinations: BlockDevice[]; verify: boolean; autoBlockmapping: boolean; decompressFirst: boolean; - onProgress: sdk.multiWrite.OnProgressFunction; - onFail: sdk.multiWrite.OnFailFunction; + onProgress: OnProgressFunction; + onFail: OnFailFunction; }): Promise { - const { - sourceMetadata, - failures, - bytesWritten, - } = await sdk.multiWrite.decompressThenFlash({ + const { sourceMetadata, failures, bytesWritten } = await decompressThenFlash({ source, destinations, onFail, @@ -149,7 +156,7 @@ async function writeAndValidate({ }; for (const [destination, error] of failures) { const err = error as FlashError; - const drive = destination as sdk.sourceDestination.BlockDevice; + const drive = destination as BlockDevice; err.device = drive.device; err.description = drive.description; result.errors.push(err); @@ -201,7 +208,7 @@ ipc.connectTo(IPC_SERVER_ID, () => { * @example * writer.on('progress', onProgress) */ - const onProgress = (state: sdk.multiWrite.MultiDestinationProgress) => { + const onProgress = (state: MultiDestinationProgress) => { ipc.of[IPC_SERVER_ID].emit('state', state); }; @@ -237,10 +244,7 @@ ipc.connectTo(IPC_SERVER_ID, () => { * @example * writer.on('fail', onFail) */ - const onFail = ( - destination: sdk.sourceDestination.SourceDestination, - error: Error, - ) => { + const onFail = (destination: SourceDestination, error: Error) => { ipc.of[IPC_SERVER_ID].emit('fail', { // TODO: device should be destination // @ts-ignore (destination.drive is private) @@ -257,7 +261,7 @@ ipc.connectTo(IPC_SERVER_ID, () => { log(`Auto blockmapping: ${options.autoBlockmapping}`); log(`Decompress first: ${options.decompressFirst}`); const dests = options.destinations.map((destination) => { - return new sdk.sourceDestination.BlockDevice({ + return new BlockDevice({ drive: destination, unmountOnSuccess: options.unmountOnSuccess, write: true, @@ -298,7 +302,6 @@ ipc.connectTo(IPC_SERVER_ID, () => { await delay(DISCONNECT_DELAY); await terminate(exitCode); } catch (error) { - log(`Error: ${error.message}`); exitCode = GENERAL_ERROR; ipc.of[IPC_SERVER_ID].emit('error', toJSON(error)); } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 5b334528..e3833180 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1313,9 +1313,9 @@ } }, "@balena/apple-plist": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@balena/apple-plist/-/apple-plist-0.0.2.tgz", - "integrity": "sha512-pipB4z1nW0YkIN1B5CgcPLzwagkAnmPF5KEuEntE5Pg5F8kNAxmED3LEF1VusAVqdZl6YwtjILzqAmykmRvvIw==", + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@balena/apple-plist/-/apple-plist-0.0.3.tgz", + "integrity": "sha512-OCb2lH6twxm0EX4UjMyK9SB8BKqhDA+8NAanThsheALJ2Jys9jsgpnixUakrGaq3qKeNITVoC0NJ4s4Q4bKRfQ==", "dev": true, "requires": { "sax": "^1.2.4" @@ -1367,12 +1367,12 @@ "dev": true }, "@balena/udif": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@balena/udif/-/udif-1.1.0.tgz", - "integrity": "sha512-iZ1GyKVNUcqNQOUem7etcrhzOanRVnuIrNqgcKZiCHunL8aextTdHeEMkY3xEgXpZWTufzDAimVmdrgeUqzT5Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@balena/udif/-/udif-1.1.1.tgz", + "integrity": "sha512-7o+R86ErTbg5RSsmnEDkMPvL8XqNpjg0NwFMmGxUr9f5Ukbmdke+jeJglRfztFE0LFY7RClcjRwbXvZoAbLMEg==", "dev": true, "requires": { - "@balena/apple-plist": "^0.0.2", + "@balena/apple-plist": "0.0.3", "apple-data-compression": "^0.4.1", "cyclic-32": "^1.1.0", "unbzip2-stream": "github:balena-io-modules/unbzip2-stream#4a54f56a25b58950f9e4277c56db2912d62242e7" @@ -3274,15 +3274,15 @@ "dev": true }, "balena-image-fs": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/balena-image-fs/-/balena-image-fs-7.0.4.tgz", - "integrity": "sha512-6jyHqP4nWd2T+XZqAzVVO9Jv+TReNAwODTSBk/k88fGUPmaAy6gHZ2+0+YxzKBQrNr0iFxtkf91UNRv68wehbg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/balena-image-fs/-/balena-image-fs-7.0.6.tgz", + "integrity": "sha512-LnLVQq9Um1/bmfgOuPRsndCpZIhHVdp7Na3Aq2sX2WUvsUhhXkpEeaer9K9kecWeVEzdqUWJARVXg82Xmke4og==", "dev": true, "requires": { - "ext2fs": "^3.0.3", + "ext2fs": "^3.0.5", "fatfs": "^0.10.7", - "file-disk": "^8.0.0", - "partitioninfo": "^6.0.1", + "file-disk": "^8.0.1", + "partitioninfo": "^6.0.2", "typed-error": "^3.2.0" } }, @@ -3418,9 +3418,9 @@ } }, "blockmap": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/blockmap/-/blockmap-4.0.2.tgz", - "integrity": "sha512-jeQSY/yAc/URhOoK/odQtqaIV9wiSB5KKRfERD1pnlkyOciBQwYuZ9Lvt/v8dCdVmn53vNlMKLm4h5Esy+WcnQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/blockmap/-/blockmap-4.0.3.tgz", + "integrity": "sha512-FNNohgfxiRKSSwxwbxYoT7qS2g6tTLevlQbLUm72Bzd31yAu+++ZJAV7lwN2MOwtiEC20lNqcsprxqdW5KTZug==", "dev": true, "requires": { "debug": "^4.1.1", @@ -5787,9 +5787,9 @@ "dev": true }, "drivelist": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/drivelist/-/drivelist-9.2.1.tgz", - "integrity": "sha512-oiMDLWUOhoqvVWDvjSrWcz2I42dNuH0Pf1SZlEr86I413n7XoY/YANnqipSynpe86arBW4EbNur7VAl5h8QQ3Q==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/drivelist/-/drivelist-9.2.2.tgz", + "integrity": "sha512-kuigQbvkc9+Y6Rf36d9nv4g4PB19UUPOvxRdQE3JEtggCqdxYCPEsNm6WYOudkfdMIFnHtmbS35QowL/hI/sGQ==", "dev": true, "requires": { "bindings": "^1.3.0", @@ -7357,36 +7357,36 @@ "dev": true }, "etcher-sdk": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-5.1.5.tgz", - "integrity": "sha512-TXyfxbfJ7Zkw3EWavA3nc7F13EAs8n0BogdZqh0bHhdbQ+vNl1h2+O1F6rrFYqwS01UsXw6YZMXXCOjwYOs04A==", + "version": "5.1.10", + "resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-5.1.10.tgz", + "integrity": "sha512-tCHY6v4txJr6+3KCIYhaLem6U3ZTEiXRtchMZiuZO6X9t2w8U5ntn6RgHbs7YIixrr/17o1aRUnqPKsXrLbDHQ==", "dev": true, "requires": { - "@balena/udif": "^1.1.0", + "@balena/udif": "^1.1.1", "@ronomon/direct-io": "^3.0.1", "aws4-axios": "^1.12.0", "axios": "^0.19.2", - "balena-image-fs": "^7.0.4", - "blockmap": "^4.0.1", + "balena-image-fs": "^7.0.6", + "blockmap": "^4.0.3", "check-disk-space": "^2.1.0", "cyclic-32": "^1.1.0", "debug": "^3.1.0", - "drivelist": "^9.2.1", - "file-disk": "^8.0.0", + "drivelist": "^9.2.2", + "file-disk": "^8.0.1", "file-type": "^8.0.0", - "gzip-stream": "^1.1.1", + "gzip-stream": "^1.1.2", "lzma-native": "^6.0.0", - "mountutils": "^1.3.18", - "node-raspberrypi-usbboot": "^0.2.9", + "mountutils": "^1.3.20", + "node-raspberrypi-usbboot": "^0.2.10", "outdent": "^0.7.0", - "partitioninfo": "^6.0.1", + "partitioninfo": "^6.0.2", "rwmutex": "^1.0.0", "tslib": "^2.0.0", "unbzip2-stream": "github:balena-io-modules/unbzip2-stream#4a54f56a25b58950f9e4277c56db2912d62242e7", "unzip-stream": "^0.3.0", "xxhash": "^0.3.0", "yauzl": "^2.9.2", - "zip-part-stream": "^1.0.2" + "zip-part-stream": "^1.0.3" }, "dependencies": { "debug": { @@ -7548,9 +7548,9 @@ } }, "ext2fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ext2fs/-/ext2fs-3.0.3.tgz", - "integrity": "sha512-KW7pKOd0IhEDhLrZkU186zl4uh2QGOJZ474x0+dxwt9uCrUrSqV5V4jBTr4q0IMNkMvHiSrBmx4CHK1Wd5spjQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/ext2fs/-/ext2fs-3.0.5.tgz", + "integrity": "sha512-QHnfxD7C9jjg1HR5vuZ+oe+IPTM3XwY8OAWU2y2TFUhXXOOf6J7P0M9eQFXDaEUYnT2trdYjJaJQUrldMmhfiQ==", "dev": true }, "extend": { @@ -7795,9 +7795,9 @@ } }, "file-disk": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-disk/-/file-disk-8.0.0.tgz", - "integrity": "sha512-8A6YSCfrlA1ytsHWK22urpcmCgqd3v0qmVg7bdVcGl7nfDvUWbURNM8hB469DWdu/rTYcrxbx6y776fIRcchig==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/file-disk/-/file-disk-8.0.1.tgz", + "integrity": "sha512-oO1bkG2RmZnMqteiAO3Uhffj/f6PJ5WY3fdVJJuI5tDbDgW3MgQvhQsDpijX81TXCbxRAKaNFdEQABTTyjL+og==", "dev": true, "requires": { "tslib": "^2.0.0" @@ -8513,9 +8513,9 @@ "dev": true }, "gzip-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/gzip-stream/-/gzip-stream-1.1.1.tgz", - "integrity": "sha512-V4FlTwvLpd5ZPcIjUODt/NrP+yhX6pKNzKYahrcSo6WLeLz5Rvlta00DZ3D13YL7QeOC3D7IYPUGKeuN3x9cEg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/gzip-stream/-/gzip-stream-1.1.2.tgz", + "integrity": "sha512-r1nVZJGbHivD0RxzP+aGV4fs08dzh/IN5MCSR0bCa4FEPo7+azLiypR93f47NqzLZt7MSGf2f8vQ1PbfT3oNIg==", "dev": true, "requires": { "@balena/node-crc-utils": "^2.0.0", @@ -11208,9 +11208,9 @@ "dev": true }, "mountutils": { - "version": "1.3.19", - "resolved": "https://registry.npmjs.org/mountutils/-/mountutils-1.3.19.tgz", - "integrity": "sha512-U2ZA26fg43cGxZHh6nxHPIUvkZWyFVbsO/5QDFpjgZHhZRk4oD4jJlKuo/X42fSyMvJ2+3jKRKPmBh/cxZ0WQw==", + "version": "1.3.20", + "resolved": "https://registry.npmjs.org/mountutils/-/mountutils-1.3.20.tgz", + "integrity": "sha512-T61cRGb6xDs8yBvzzI+DiYMEUuWVaVw9hZABiTHy4gxfaFJsg8OwgaLMzmH2/SCcxsEUNGO1ACx7Cq7TJ3AcEA==", "dev": true, "requires": { "bindings": "^1.3.0", @@ -11734,9 +11734,9 @@ } }, "node-raspberrypi-usbboot": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/node-raspberrypi-usbboot/-/node-raspberrypi-usbboot-0.2.9.tgz", - "integrity": "sha512-2HJbtb+yfmKjzVTCAfoIg0/Ur3kAqVNdQGx0U/hnOcgpZ22SXzSmsvr69NgRa4QqdCboXPfKS8mJgefBtXYNbg==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/node-raspberrypi-usbboot/-/node-raspberrypi-usbboot-0.2.10.tgz", + "integrity": "sha512-wLl6DMv707iQdxNFVjj09y7+Opgpiazuoil3ljY6c91ci15GXFpuajBGoZIseJPqoWu3uYbvmODO9slma6bVJQ==", "dev": true, "requires": { "@balena.io/usb": "^1.3.12", @@ -12445,12 +12445,12 @@ "dev": true }, "partitioninfo": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/partitioninfo/-/partitioninfo-6.0.1.tgz", - "integrity": "sha512-hmLiVz5G6GPzd1TsAuHTHDoSrKqb7cNr2zhJ+fwMhCg2pRoz7vftaP9kL47pMwusO0jWUwkw62oKfHfv0Wa5+A==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/partitioninfo/-/partitioninfo-6.0.2.tgz", + "integrity": "sha512-LxmwiC0tSqlTvjL7SYH0MQYRwQkUTfcm55mZPG8+jPNmhhYfhr7QiYr6FUAaF3ixHlhF5pV/YcSLgp8DXq+jYQ==", "dev": true, "requires": { - "file-disk": "^8.0.0", + "file-disk": "^8.0.1", "gpt": "^2.0.4", "mbr": "^1.1.3", "tslib": "^2.0.0", @@ -14950,8 +14950,8 @@ } }, "sudo-prompt": { - "version": "github:zvin/sudo-prompt#81cab70c1f3f816b71539c4c5d7ecf1309094f8c", - "from": "github:zvin/sudo-prompt#workaround-windows-amperstand-in-username", + "version": "github:zvin/sudo-prompt#7cdede2f0da28fbcc2db48402d7d935f3a825c91", + "from": "github:zvin/sudo-prompt#7cdede2f0da28fbcc2db48402d7d935f3a825c91", "dev": true }, "sumchecker": { @@ -15006,9 +15006,9 @@ "dev": true }, "sys-class-rgb-led": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sys-class-rgb-led/-/sys-class-rgb-led-2.1.0.tgz", - "integrity": "sha512-ckjrMCWWwg1J4d+B3xlTPLhgK6U/2qpW1TYzCLBSULKoLk2tFchis7nDEOmcbiLfpR/8GQK1Q2CrDNleF0USHA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/sys-class-rgb-led/-/sys-class-rgb-led-2.1.1.tgz", + "integrity": "sha512-CPx01dR22xsqqgpGQ0BcKWf1hCJNTK/Y/gK/hvNEZX5PyuvUzrCYsBWgletzlaruc47RYGi/0be+ZbkIIiQjnA==", "dev": true }, "tapable": { @@ -17468,9 +17468,9 @@ "dev": true }, "zip-part-stream": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/zip-part-stream/-/zip-part-stream-1.0.2.tgz", - "integrity": "sha512-2dxIug2ydhnpv1YGRuU7muTpxx4+hoLaQoVwfysaRzWF1GV2s5BDqlTuiQQda/vdfMtKYIamSJffps+0n4QJsw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/zip-part-stream/-/zip-part-stream-1.0.3.tgz", + "integrity": "sha512-JJm6HvhvUCk7CHusOgRMvqYtMDVGj6HOQdTGxEs+ckWPysGScdZW3Y95pNZFeLZEgqbSTiDmaurLIH8osqdZiQ==", "dev": true, "requires": { "@balena/node-crc-utils": "^2.0.0", @@ -17509,4 +17509,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 5152182d..c0453402 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "electron-notarize": "^1.0.0", "electron-rebuild": "^2.3.2", "electron-updater": "^4.3.5", - "etcher-sdk": "^5.1.5", + "etcher-sdk": "^5.1.10", "file-loader": "^6.0.0", "husky": "^4.2.5", "immutable": "^3.8.1", @@ -102,8 +102,8 @@ "spectron": "^11.0.0", "string-replace-loader": "^2.3.0", "styled-components": "^5.1.0", - "sudo-prompt": "github:zvin/sudo-prompt#workaround-windows-amperstand-in-username", - "sys-class-rgb-led": "^2.1.0", + "sudo-prompt": "github:zvin/sudo-prompt#7cdede2f0da28fbcc2db48402d7d935f3a825c91", + "sys-class-rgb-led": "^2.1.1", "tmp": "^0.2.1", "ts-loader": "^8.0.0", "ts-node": "^9.0.0", diff --git a/repo.yml b/repo.yml index e46bdd86..d7eca207 100644 --- a/repo.yml +++ b/repo.yml @@ -8,4 +8,13 @@ sentry: triggerNotification: version: 1.5.81 stagingPercentage: 100 - +upstream: + - repo: etcher-sdk + url: https://github.com/balena-io-modules/etcher-sdk + module: 'etcher-sdk' + - repo: sys-class-rgb-led + url: https://github.com/balena-io-modules/sys-class-rgb-led + module: sys-class-rgb-led + - repo: rendition + url: https://github.com/balena-io-modules/rendition + module: rendition diff --git a/tests/spectron/runner.spec.ts b/tests/spectron/runner.spec.ts index f8973e8e..065c9fb0 100644 --- a/tests/spectron/runner.spec.ts +++ b/tests/spectron/runner.spec.ts @@ -46,7 +46,10 @@ describe('Spectron', function () { expect(bounds.height).to.be.above(0); expect(bounds.width).to.be.above(0); expect(await app.browserWindow.isMinimized()).to.be.false; - expect(await app.browserWindow.isVisible()).to.be.true; + expect( + (await app.browserWindow.isVisible()) || + (await app.browserWindow.isFocused()), + ).to.be.true; }); it('should set a proper title', async () => {