diff --git a/FAQ.md b/FAQ.md index 2f0a63f3..97657ea8 100644 --- a/FAQ.md +++ b/FAQ.md @@ -43,4 +43,4 @@ Etcher requires an available [polkit authentication agent](https://wiki.archlinu ## May I run Etcher in older macOS versions? -Etcher GUI is based on the [Electron](http://electron.atom.io/) framework, [which only supports macOS 10.9 and newer versions](https://github.com/electron/electron/blob/master/docs/tutorial/support.md#supported-platforms). +Etcher GUI is based on the [Electron](http://electron.atom.io/) framework, [which only supports macOS 10.10 and newer versions](https://github.com/electron/electron/blob/master/docs/tutorial/support.md#supported-platforms). diff --git a/Makefile b/Makefile index a0ca7f8d..be4484d0 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # --------------------------------------------------------------------- RESIN_SCRIPTS ?= ./scripts/resin -export NPM_VERSION ?= 6.14.5 +export NPM_VERSION ?= 6.14.8 S3_BUCKET = artifacts.ci.balena-cloud.com # This directory will be completely deleted by the `clean` rule diff --git a/SUPPORT.md b/SUPPORT.md index b5b129d6..f276a8cd 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -4,6 +4,13 @@ Getting help with Etcher There are various ways to get support for Etcher if you experience an issue or have an idea you'd like to share with us. +Documentation +------ + +We have answers to a variety of frequently asked questions in the [user +documentation][documentation] and also in the [FAQs][faq] on the Etcher website. + + Forums ------ @@ -32,3 +39,5 @@ one][new-issue]. [discourse]: https://forums.balena.io/c/etcher [issues]: https://github.com/balena-io/etcher/issues [new-issue]: https://github.com/balena-io/etcher/issues/new +[documentation]: https://github.com/balena-io/etcher/blob/master/docs/USER-DOCUMENTATION.md +[faq]: https://etcher.io diff --git a/lib/gui/app/components/drive-selector/drive-selector.tsx b/lib/gui/app/components/drive-selector/drive-selector.tsx index 4a06064f..cd5951ca 100644 --- a/lib/gui/app/components/drive-selector/drive-selector.tsx +++ b/lib/gui/app/components/drive-selector/drive-selector.tsx @@ -74,6 +74,8 @@ function isDrivelistDrive(drive: Drive): drive is DrivelistDrive { const DrivesTable = styled((props: GenericTableProps) => ( {...props} /> ))` + border-bottom: none; + [data-display='table-head'], [data-display='table-body'] { > [data-display='table-row'] > [data-display='table-cell'] { @@ -303,9 +305,9 @@ export class DriveSelector extends React.Component< case compatibility.system(): return warning.systemDrive(); case compatibility.tooSmall(): - const recommendedDriveSize = + const size = this.state.image?.recommendedDriveSize || this.state.image?.size || 0; - return warning.unrecommendedDriveSize({ recommendedDriveSize }, drive); + return warning.tooSmall({ size }, drive); } } diff --git a/lib/gui/app/components/flash-results/flash-results.tsx b/lib/gui/app/components/flash-results/flash-results.tsx index dad0d822..05de2b3d 100644 --- a/lib/gui/app/components/flash-results/flash-results.tsx +++ b/lib/gui/app/components/flash-results/flash-results.tsx @@ -17,7 +17,6 @@ import CircleSvg from '@fortawesome/fontawesome-free/svgs/solid/circle.svg'; import CheckCircleSvg from '@fortawesome/fontawesome-free/svgs/solid/check-circle.svg'; import TimesCircleSvg from '@fortawesome/fontawesome-free/svgs/solid/times-circle.svg'; -import * as _ from 'lodash'; import outdent from 'outdent'; import * as React from 'react'; import { Flex, FlexProps, Link, TableColumn, Txt } from 'rendition'; @@ -104,6 +103,19 @@ const columns: Array> = [ }, ]; +function getEffectiveSpeed(results: { + sourceMetadata: { + size: number; + blockmappedSize?: number; + }; + averageFlashingSpeed: number; +}) { + const flashedSize = + results.sourceMetadata.blockmappedSize ?? results.sourceMetadata.size; + const timeSpent = flashedSize / results.averageFlashingSpeed; + return results.sourceMetadata.size / timeSpent; +} + export function FlashResults({ goToMain, image = '', @@ -117,10 +129,9 @@ export function FlashResults({ errors: FlashError[]; skip: boolean; results: { - bytesWritten: number; sourceMetadata: { size: number; - blockmappedSize: number; + blockmappedSize?: number; }; averageFlashingSpeed: number; devices: { failed: number; successful: number }; @@ -129,11 +140,7 @@ export function FlashResults({ const [showErrorsInfo, setShowErrorsInfo] = React.useState(false); const allFailed = !skip && results.devices.successful === 0; const someFailed = results.devices.failed !== 0 || errors.length !== 0; - const effectiveSpeed = _.round( - bytesToMegabytes( - results.sourceMetadata.size / - (results.sourceMetadata.blockmappedSize / results.averageFlashingSpeed), - ), + const effectiveSpeed = bytesToMegabytes(getEffectiveSpeed(results)).toFixed( 1, ); return ( diff --git a/lib/gui/app/components/settings/settings.tsx b/lib/gui/app/components/settings/settings.tsx index 6ade247b..d6ac584b 100644 --- a/lib/gui/app/components/settings/settings.tsx +++ b/lib/gui/app/components/settings/settings.tsx @@ -16,7 +16,6 @@ import GithubSvg from '@fortawesome/fontawesome-free/svgs/brands/github.svg'; import * as _ from 'lodash'; -import * as os from 'os'; import * as React from 'react'; import { Flex, Checkbox, Txt } from 'rendition'; @@ -26,40 +25,25 @@ import * as analytics from '../../modules/analytics'; import { open as openExternal } from '../../os/open-external/services/open-external'; import { Modal } from '../../styled-components'; -const platform = os.platform(); - interface Setting { name: string; label: string | JSX.Element; - options?: { - description: string; - confirmLabel: string; - }; - hide?: boolean; } async function getSettingsList(): Promise { - return [ + const list: Setting[] = [ { name: 'errorReporting', label: 'Anonymously report errors and usage statistics to balena.io', }, - { - name: 'unmountOnSuccess', - /** - * On Windows, "Unmounting" basically means "ejecting". - * On top of that, Windows users are usually not even - * familiar with the meaning of "unmount", which comes - * from the UNIX world. - */ - label: `${platform === 'win32' ? 'Eject' : 'Auto-unmount'} on success`, - }, - { + ]; + if (['appimage', 'nsis', 'dmg'].includes(packageType)) { + list.push({ name: 'updatesEnabled', label: 'Auto-updates enabled', - hide: ['rpm', 'deb'].includes(packageType), - }, - ]; + }); + } + return list; } interface SettingsModalProps { @@ -86,25 +70,14 @@ export function SettingsModal({ toggleModal }: SettingsModalProps) { })(); }); - const toggleSetting = async ( - setting: string, - options?: Setting['options'], - ) => { + const toggleSetting = async (setting: string) => { const value = currentSettings[setting]; - const dangerous = options !== undefined; - - analytics.logEvent('Toggle setting', { - setting, - value, - dangerous, - }); - + analytics.logEvent('Toggle setting', { setting, value }); await settings.set(setting, !value); setCurrentSettings({ ...currentSettings, [setting]: !value, }); - return; }; return ( @@ -118,14 +91,14 @@ export function SettingsModal({ toggleModal }: SettingsModalProps) { > {settingsList.map((setting: Setting, i: number) => { - return setting.hide ? null : ( + return ( toggleSetting(setting.name, setting.options)} + onChange={() => toggleSetting(setting.name)} /> ); diff --git a/lib/gui/app/css/main.css b/lib/gui/app/css/main.css index fcf89cf1..0671d8a9 100644 --- a/lib/gui/app/css/main.css +++ b/lib/gui/app/css/main.css @@ -64,3 +64,19 @@ input[type="checkbox"] + div { #rendition-tooltip-root > div { font-family: "SourceSansPro", sans-serif; } + +/* HIGH-CONTRAST CHANGES */ +input[type="text"], +input[type="checkbox"] ~ div, +input[type="checkbox"] ~ span { + border-color: #b5b5b5 !important; +} + +[data-display="table-head"] + > [data-display="table-row"] + > [data-display="table-cell"], +[data-display="table-body"] + > [data-display="table-row"] + > [data-display="table-cell"] { + border-bottom: 1px solid #b5b5b5 !important; +} diff --git a/lib/gui/app/models/flash-state.ts b/lib/gui/app/models/flash-state.ts index 4504551f..f5479e5c 100644 --- a/lib/gui/app/models/flash-state.ts +++ b/lib/gui/app/models/flash-state.ts @@ -85,6 +85,10 @@ export function addFailedDeviceError({ const failedDeviceErrorsMap = new Map( store.getState().toJS().failedDeviceErrors, ); + if (failedDeviceErrorsMap.has(device.device)) { + // Only store the first error + return; + } failedDeviceErrorsMap.set(device.device, { description: device.description, device: device.device, diff --git a/lib/gui/app/models/leds.ts b/lib/gui/app/models/leds.ts index 38735f67..a9aa7716 100644 --- a/lib/gui/app/models/leds.ts +++ b/lib/gui/app/models/leds.ts @@ -15,7 +15,7 @@ */ import * as _ from 'lodash'; -import { AnimationFunction, Color, RGBLed } from 'sys-class-rgb-led'; +import { Animator, AnimationFunction, Color, RGBLed } from 'sys-class-rgb-led'; import { isSourceDrive, @@ -25,30 +25,14 @@ import * as settings from './settings'; import { DEFAULT_STATE, observe } from './store'; const leds: Map = new Map(); +const animator = new Animator([], 10); -function setLeds( - drivesPaths: Set, - colorOrAnimation: Color | AnimationFunction, - frequency?: number, -) { - for (const path of drivesPaths) { - const led = leds.get(path); - if (led) { - if (Array.isArray(colorOrAnimation)) { - led.setStaticColor(colorOrAnimation); - } else { - led.setAnimation(colorOrAnimation, frequency); - } - } - } -} - -const red: Color = [1, 0, 0]; -const green: Color = [0, 1, 0]; -const blue: Color = [0, 0, 1]; -const white: Color = [1, 1, 1]; +const red: Color = [0.59, 0, 0]; +const green: Color = [0, 0.59, 0]; +const blue: Color = [0, 0, 0.59]; +const white: Color = [0.04, 0.04, 0.04]; const black: Color = [0, 0, 0]; -const purple: Color = [0.5, 0, 0.5]; +const purple: Color = [0.117, 0, 0.196]; function createAnimationFunction( intensityFunction: (t: number) => number, @@ -61,16 +45,20 @@ function createAnimationFunction( } function blink(t: number) { - return Math.floor(t / 1000) % 2; + return Math.floor(t) % 2; } -function breathe(t: number) { - return (1 + Math.sin(t / 1000)) / 2; +function one(_t: number) { + return 1; } -const breatheBlue = createAnimationFunction(breathe, blue); const blinkGreen = createAnimationFunction(blink, green); const blinkPurple = createAnimationFunction(blink, purple); +const staticRed = createAnimationFunction(one, red); +const staticGreen = createAnimationFunction(one, green); +const staticBlue = createAnimationFunction(one, blue); +const staticWhite = createAnimationFunction(one, white); +const staticBlack = createAnimationFunction(one, black); interface LedsState { step: 'main' | 'flashing' | 'verifying' | 'finish'; @@ -80,6 +68,17 @@ interface LedsState { failedDrives: string[]; } +function setLeds(animation: AnimationFunction, drivesPaths: Set) { + const rgbLeds: RGBLed[] = []; + for (const path of drivesPaths) { + const led = leds.get(path); + if (led) { + rgbLeds.push(led); + } + } + return { animation, rgbLeds }; +} + // Source slot (1st slot): behaves as a target unless it is chosen as source // No drive: black // Drive plugged: blue - on @@ -110,6 +109,7 @@ export function updateLeds({ // Remove selected devices from plugged set for (const d of selectedOk) { plugged.delete(d); + unplugged.delete(d); } // Remove plugged devices from unplugged set @@ -122,38 +122,42 @@ export function updateLeds({ selectedOk.delete(d); } + const mapping: Array<{ + animation: AnimationFunction; + rgbLeds: RGBLed[]; + }> = []; // Handle source slot if (sourceDrive !== undefined) { - if (unplugged.has(sourceDrive)) { - unplugged.delete(sourceDrive); - // TODO - setLeds(new Set([sourceDrive]), breatheBlue, 2); - } else if (plugged.has(sourceDrive)) { + if (plugged.has(sourceDrive)) { plugged.delete(sourceDrive); - setLeds(new Set([sourceDrive]), blue); + mapping.push(setLeds(staticBlue, new Set([sourceDrive]))); } } if (step === 'main') { - setLeds(unplugged, black); - setLeds(plugged, black); - setLeds(selectedOk, white); - setLeds(selectedFailed, white); + mapping.push( + setLeds(staticBlack, new Set([...unplugged, ...plugged])), + setLeds(staticWhite, new Set([...selectedOk, ...selectedFailed])), + ); } else if (step === 'flashing') { - setLeds(unplugged, black); - setLeds(plugged, black); - setLeds(selectedOk, blinkPurple, 2); - setLeds(selectedFailed, red); + mapping.push( + setLeds(staticBlack, new Set([...unplugged, ...plugged])), + setLeds(blinkPurple, selectedOk), + setLeds(staticRed, selectedFailed), + ); } else if (step === 'verifying') { - setLeds(unplugged, black); - setLeds(plugged, black); - setLeds(selectedOk, blinkGreen, 2); - setLeds(selectedFailed, red); + mapping.push( + setLeds(staticBlack, new Set([...unplugged, ...plugged])), + setLeds(blinkGreen, selectedOk), + setLeds(staticRed, selectedFailed), + ); } else if (step === 'finish') { - setLeds(unplugged, black); - setLeds(plugged, black); - setLeds(selectedOk, green); - setLeds(selectedFailed, red); + mapping.push( + setLeds(staticBlack, new Set([...unplugged, ...plugged])), + setLeds(staticGreen, selectedOk), + setLeds(staticRed, selectedFailed), + ); } + animator.mapping = mapping; } interface DeviceFromState { @@ -189,7 +193,7 @@ function stateObserver(state: typeof DEFAULT_STATE) { selectedDrivesPaths = s.devicePaths; } const failedDevicePaths = s.failedDeviceErrors.map( - ([devicePath]: [string]) => devicePath, + ([, { devicePath }]: [string, { devicePath: string }]) => devicePath, ); const newLedsState = { step, diff --git a/lib/gui/app/models/settings.ts b/lib/gui/app/models/settings.ts index 5c7b5ee9..25c9cd7a 100644 --- a/lib/gui/app/models/settings.ts +++ b/lib/gui/app/models/settings.ts @@ -77,8 +77,7 @@ export async function writeConfigFile( const DEFAULT_SETTINGS: _.Dictionary = { errorReporting: true, - unmountOnSuccess: true, - updatesEnabled: !_.includes(['rpm', 'deb'], packageJSON.packageType), + updatesEnabled: ['appimage', 'nsis', 'dmg'].includes(packageJSON.packageType), desktopNotifications: true, autoBlockmapping: true, decompressFirst: true, diff --git a/lib/gui/app/modules/image-writer.ts b/lib/gui/app/modules/image-writer.ts index 09a78e2d..220fe64a 100644 --- a/lib/gui/app/modules/image-writer.ts +++ b/lib/gui/app/modules/image-writer.ts @@ -151,11 +151,7 @@ async function performWrite( let cancelled = false; let skip = false; ipc.serve(); - const { - unmountOnSuccess, - autoBlockmapping, - decompressFirst, - } = await settings.getAll(); + const { autoBlockmapping, decompressFirst } = await settings.getAll(); return await new Promise((resolve, reject) => { ipc.server.on('error', (error) => { terminateServer(); @@ -174,7 +170,6 @@ async function performWrite( driveCount: drives.length, uuid: flashState.getFlashUuid(), flashInstanceUuid: flashState.getFlashUuid(), - unmountOnSuccess, }; ipc.server.on('fail', ({ device, error }) => { @@ -211,7 +206,6 @@ async function performWrite( destinations: drives, SourceType: image.SourceType.name, autoBlockmapping, - unmountOnSuccess, decompressFirst, }); }); @@ -290,7 +284,6 @@ export async function flash( uuid: flashState.getFlashUuid(), status: 'started', flashInstanceUuid: flashState.getFlashUuid(), - unmountOnSuccess: await settings.get('unmountOnSuccess'), }; analytics.logEvent('Flash', analyticsData); @@ -345,7 +338,6 @@ export async function cancel(type: string) { driveCount: drives.length, uuid: flashState.getFlashUuid(), flashInstanceUuid: flashState.getFlashUuid(), - unmountOnSuccess: await settings.get('unmountOnSuccess'), status, }; analytics.logEvent('Cancel', analyticsData); diff --git a/lib/gui/modules/child-writer.ts b/lib/gui/modules/child-writer.ts index 713151ba..dec36144 100644 --- a/lib/gui/modules/child-writer.ts +++ b/lib/gui/modules/child-writer.ts @@ -167,7 +167,6 @@ async function writeAndValidate({ interface WriteOptions { image: SourceMetadata; destinations: DrivelistDrive[]; - unmountOnSuccess: boolean; autoBlockmapping: boolean; decompressFirst: boolean; SourceType: string; @@ -257,13 +256,12 @@ ipc.connectTo(IPC_SERVER_ID, () => { const imagePath = options.image.path; log(`Image: ${imagePath}`); log(`Devices: ${destinations.join(', ')}`); - log(`Umount on success: ${options.unmountOnSuccess}`); log(`Auto blockmapping: ${options.autoBlockmapping}`); log(`Decompress first: ${options.decompressFirst}`); const dests = options.destinations.map((destination) => { return new BlockDevice({ drive: destination, - unmountOnSuccess: options.unmountOnSuccess, + unmountOnSuccess: true, write: true, direct: true, }); diff --git a/lib/shared/messages.ts b/lib/shared/messages.ts index c0c1e81c..7a28cb7f 100644 --- a/lib/shared/messages.ts +++ b/lib/shared/messages.ts @@ -81,13 +81,10 @@ export const compatibility = { } as const; export const warning = { - unrecommendedDriveSize: ( - image: { recommendedDriveSize: number }, - drive: { device: string; size: number }, - ) => { + tooSmall: (source: { size: number }, target: { size: number }) => { return outdent({ newline: ' ' })` - This image recommends a ${prettyBytes(image.recommendedDriveSize)} - drive, however ${drive.device} is only ${prettyBytes(drive.size)}. + The selected source is ${prettyBytes(source.size - target.size)} + larger than this drive. `; }, diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index b998cdb1..957184db 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -5864,9 +5864,9 @@ } }, "electron": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-9.3.3.tgz", - "integrity": "sha512-xghKeUY1qgnEcJ5w2rXo/toH+8NT2Dktx2aAxBNPV7CIJr3mejJJAPwLbycwtddzr37tgKxHeHlc8ivfKtMkJQ==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-9.4.0.tgz", + "integrity": "sha512-hOC4q0jkb+UDYZRy8vrZ1IANnq+jznZnbkD62OEo06nU+hIbp2IrwDRBNuSLmQ3cwZMVir0WSIA1qEVK0PkzGA==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -7357,9 +7357,9 @@ "dev": true }, "etcher-sdk": { - "version": "5.1.10", - "resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-5.1.10.tgz", - "integrity": "sha512-tCHY6v4txJr6+3KCIYhaLem6U3ZTEiXRtchMZiuZO6X9t2w8U5ntn6RgHbs7YIixrr/17o1aRUnqPKsXrLbDHQ==", + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/etcher-sdk/-/etcher-sdk-5.1.11.tgz", + "integrity": "sha512-aS5gbclUoBF+8NOV2R2MJN52BOYKJHc+gjlZF3xZh1hVoglVb0AtCZpFFfTk8/cDn2SvrfAv03/amXaJxJjaPQ==", "dev": true, "requires": { "@balena/udif": "^1.1.1", @@ -15006,9 +15006,9 @@ "dev": true }, "sys-class-rgb-led": { - "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==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sys-class-rgb-led/-/sys-class-rgb-led-3.0.0.tgz", + "integrity": "sha512-e5vMYgWgDFfXMN67lbTW6niSxzm3eiD8A8hEciUtOUexfYGM6lpd6dH6bERq2LL99mmBYFSxYFZTMWHga4xe7Q==", "dev": true }, "tapable": { @@ -17509,4 +17509,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 2fa013b2..7cee4668 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "webpack": "webpack", "watch": "webpack --watch", "concourse-build-electron": "npm run webpack", - "concourse-test": "npx npm@6.14.5 test", - "concourse-test-electron": "npx npm@6.14.5 test" + "concourse-test": "npx npm@6.14.8 test", + "concourse-test-electron": "npx npm@6.14.8 test" }, "husky": { "hooks": { @@ -71,13 +71,13 @@ "css-loader": "^4.2.1", "d3": "^4.13.0", "debug": "^4.2.0", - "electron": "9.3.3", + "electron": "9.4.0", "electron-builder": "^22.9.1", "electron-mocha": "^9.3.2", "electron-notarize": "^1.0.0", "electron-rebuild": "^2.3.2", "electron-updater": "^4.3.5", - "etcher-sdk": "^5.1.10", + "etcher-sdk": "^5.1.11", "file-loader": "^6.0.0", "husky": "^4.2.5", "immutable": "^3.8.1", @@ -103,7 +103,7 @@ "string-replace-loader": "^2.3.0", "styled-components": "^5.1.0", "sudo-prompt": "github:zvin/sudo-prompt#7cdede2f0da28fbcc2db48402d7d935f3a825c91", - "sys-class-rgb-led": "^2.1.1", + "sys-class-rgb-led": "^3.0.0", "tmp": "^0.2.1", "ts-loader": "^8.0.0", "ts-node": "^9.0.0", diff --git a/tests/gui/modules/progress-status.spec.ts b/tests/gui/modules/progress-status.spec.ts index b892904b..f3621855 100644 --- a/tests/gui/modules/progress-status.spec.ts +++ b/tests/gui/modules/progress-status.spec.ts @@ -16,7 +16,6 @@ import { expect } from 'chai'; -import * as settings from '../../../lib/gui/app/models/settings'; import * as progressStatus from '../../../lib/gui/app/modules/progress-status'; describe('Browser: progressStatus', function () { @@ -30,8 +29,6 @@ describe('Browser: progressStatus', function () { eta: 15, speed: 100000000000000, }; - - settings.set('unmountOnSuccess', true); }); it('should report 0% if percentage == 0 but speed != 0', function () { @@ -40,22 +37,14 @@ describe('Browser: progressStatus', function () { ); }); - it('should handle percentage == 0, flashing, unmountOnSuccess', function () { + it('should handle percentage == 0, flashing', function () { this.state.speed = 0; expect(progressStatus.titleFromFlashState(this.state)).to.equal( '0% Flashing...', ); }); - it('should handle percentage == 0, flashing, !unmountOnSuccess', function () { - this.state.speed = 0; - settings.set('unmountOnSuccess', false); - expect(progressStatus.titleFromFlashState(this.state)).to.equal( - '0% Flashing...', - ); - }); - - it('should handle percentage == 0, verifying, unmountOnSuccess', function () { + it('should handle percentage == 0, verifying', function () { this.state.speed = 0; this.state.type = 'verifying'; expect(progressStatus.titleFromFlashState(this.state)).to.equal( @@ -63,31 +52,14 @@ describe('Browser: progressStatus', function () { ); }); - it('should handle percentage == 0, verifying, !unmountOnSuccess', function () { - this.state.speed = 0; - this.state.type = 'verifying'; - settings.set('unmountOnSuccess', false); - expect(progressStatus.titleFromFlashState(this.state)).to.equal( - '0% Validating...', - ); - }); - - it('should handle percentage == 50, flashing, unmountOnSuccess', function () { + it('should handle percentage == 50, flashing', function () { this.state.percentage = 50; expect(progressStatus.titleFromFlashState(this.state)).to.equal( '50% Flashing...', ); }); - it('should handle percentage == 50, flashing, !unmountOnSuccess', function () { - this.state.percentage = 50; - settings.set('unmountOnSuccess', false); - expect(progressStatus.titleFromFlashState(this.state)).to.equal( - '50% Flashing...', - ); - }); - - it('should handle percentage == 50, verifying, unmountOnSuccess', function () { + it('should handle percentage == 50, verifying', function () { this.state.percentage = 50; this.state.type = 'verifying'; expect(progressStatus.titleFromFlashState(this.state)).to.equal( @@ -95,31 +67,14 @@ describe('Browser: progressStatus', function () { ); }); - it('should handle percentage == 50, verifying, !unmountOnSuccess', function () { - this.state.percentage = 50; - this.state.type = 'verifying'; - settings.set('unmountOnSuccess', false); - expect(progressStatus.titleFromFlashState(this.state)).to.equal( - '50% Validating...', - ); - }); - - it('should handle percentage == 100, flashing, unmountOnSuccess', function () { + it('should handle percentage == 100, flashing', function () { this.state.percentage = 100; expect(progressStatus.titleFromFlashState(this.state)).to.equal( 'Finishing...', ); }); - it('should handle percentage == 100, flashing, !unmountOnSuccess', function () { - this.state.percentage = 100; - settings.set('unmountOnSuccess', false); - expect(progressStatus.titleFromFlashState(this.state)).to.equal( - 'Finishing...', - ); - }); - - it('should handle percentage == 100, verifying, unmountOnSuccess', function () { + it('should handle percentage == 100, verifying', function () { this.state.percentage = 100; this.state.type = 'verifying'; expect(progressStatus.titleFromFlashState(this.state)).to.equal( @@ -127,9 +82,8 @@ describe('Browser: progressStatus', function () { ); }); - it('should handle percentage == 100, validatinf, !unmountOnSuccess', function () { + it('should handle percentage == 100, validating', function () { this.state.percentage = 100; - settings.set('unmountOnSuccess', false); expect(progressStatus.titleFromFlashState(this.state)).to.equal( 'Finishing...', );