diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index 551176f6aba..6bb7da0e101 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -46,15 +46,34 @@ runs: with: python-version: '3.11' - - name: Setup Virtual Drive + - name: Setup Virtual Drive on MacOS if: runner.os == 'macOS' shell: bash run: | hdiutil create -size 4096m -layout NONE -o virtual_test_disk.dmg virtual_path=$(hdiutil attach -nomount virtual_test_disk.dmg) - echo "VIRTUAL_TEST_DISK=${virtual_path}" >> $GITHUB_ENV + echo "TARGET_DRIVE=${virtual_path}" >> $GITHUB_ENV echo "ETCHER_INCLUDE_VIRTUAL_DRIVES=1" >> $GITHUB_ENV + - name: Setup Virtual Drive on Linux + if: runner.os == 'Linux' + shell: bash + run: | + dd if=/dev/zero of=virtual_test_disk.img bs=1M count=4096 + virtual_path=$(sudo losetup -f --show virtual_test_disk.img) + echo "TARGET_DRIVE=${virtual_path}" >> $GITHUB_ENV + echo "ETCHER_INCLUDE_VIRTUAL_DRIVES=1" >> $GITHUB_ENV + + - name: Setup Virtual Drive on Windows + if: runner.os == 'Windows' + shell: pwsh + run: | + $virtual_path = New-VHD -Path virtual_test_disk.vhdx -SizeBytes 4GB + Mount-VHD -Path $virtual_path + $virtual_path = Get-DiskImage -ImagePath virtual_test_disk.vhdx | Get-Partition | Get-Volume + echo "TARGET_DRIVE=${virtual_path}" >> $env:GITHUB_ENV + echo "ETCHER_INCLUDE_VIRTUAL_DRIVES=1" >> $env:GITHUB_ENV + - name: Test release shell: bash run: | diff --git a/.gitignore b/.gitignore index f523e5fe176..eb19b1e4b95 100644 --- a/.gitignore +++ b/.gitignore @@ -120,4 +120,10 @@ secrets/WINDOWS_SIGNING.pfx #local development .yalc -yalc.lock \ No newline at end of file +yalc.lock + +# Test assets +virtual_test_disk.dmg +virtual_test_disk.img +virtual_test_disk.vhd +screenshots/ \ No newline at end of file diff --git a/lib/gui/app/components/drive-selector/drive-selector.tsx b/lib/gui/app/components/drive-selector/drive-selector.tsx index 2e598c82aaa..864ab91ff3d 100644 --- a/lib/gui/app/components/drive-selector/drive-selector.tsx +++ b/lib/gui/app/components/drive-selector/drive-selector.tsx @@ -419,7 +419,7 @@ export class DriveSelector extends React.Component< primary: !showWarnings, warning: showWarnings, disabled: !hasAvailableDrives(), - "data-testid": 'validate-target-button', + 'data-testid': 'validate-target-button', }} {...props} > diff --git a/lib/gui/app/components/progress-button/progress-button.tsx b/lib/gui/app/components/progress-button/progress-button.tsx index 6e435edabcc..7fb1cc95de5 100644 --- a/lib/gui/app/components/progress-button/progress-button.tsx +++ b/lib/gui/app/components/progress-button/progress-button.tsx @@ -104,7 +104,9 @@ export class ProgressButton extends React.PureComponent { }} > - {status}  + + {status}  + {position} {type && ( diff --git a/lib/gui/app/components/source-selector/source-selector.tsx b/lib/gui/app/components/source-selector/source-selector.tsx index 66e0b16503b..c41eb7cd9ad 100644 --- a/lib/gui/app/components/source-selector/source-selector.tsx +++ b/lib/gui/app/components/source-selector/source-selector.tsx @@ -165,7 +165,7 @@ const URLSelector = ({ cancel={cancel} primaryButtonProps={{ disabled: loading || !imageURL, - "data-testid":"source-url-ok-button", + 'data-testid': 'source-url-ok-button', }} action={loading ? : i18next.t('ok')} done={async () => { diff --git a/lib/util/drive-scanner.ts b/lib/util/drive-scanner.ts index 6b1d61dc7de..8219f2f8dcd 100644 --- a/lib/util/drive-scanner.ts +++ b/lib/util/drive-scanner.ts @@ -25,7 +25,8 @@ import { geteuid, platform } from 'process'; const adapters: Adapter[] = [ new BlockDeviceAdapter({ includeSystemDrives: () => true, - includeVirtualDrives: () => process.env.ETCHER_INCLUDE_VIRTUAL_DRIVES === '1', + includeVirtualDrives: () => + process.env.ETCHER_INCLUDE_VIRTUAL_DRIVES === '1', }), ]; diff --git a/tests/e2e/e2e-flash-from-file.spec.ts b/tests/e2e/e2e-flash-from-file.spec.ts index 2221f5014dc..fea720f9663 100644 --- a/tests/e2e/e2e-flash-from-file.spec.ts +++ b/tests/e2e/e2e-flash-from-file.spec.ts @@ -1,5 +1,4 @@ import { browser } from '@wdio/globals'; -import { FlashResults } from '../../lib/gui/app/components/flash-results/flash-results'; describe('Electron Testing', () => { it('should print application title', async () => { @@ -7,35 +6,37 @@ describe('Electron Testing', () => { }); it('should "flash from file"', async () => { - const flashFromFileButton = $('button[data-testid="flash-from-file"]') - await flashFromFileButton.waitForDisplayed({timeout: 10000}) + const flashFromFileButton = $('button[data-testid="flash-from-file"]'); + await flashFromFileButton.waitForDisplayed({ timeout: 10000 }); // const isDisplayed = await flashFromFileButton.isDisplayed(); await flashFromFileButton.click(); - const selectTargetButton = $('button[data-testid="select-target-button"]') - await selectTargetButton.waitForClickable({timeout: 30000}) + const selectTargetButton = $('button[data-testid="select-target-button"]'); + await selectTargetButton.waitForClickable({ timeout: 30000 }); await selectTargetButton.click(); - // TODO: Select target using ENV variable for the drive - const targetVirtualDrive = $('=/dev/disk8') - await targetVirtualDrive.waitForDisplayed({timeout: 10000}) - await targetVirtualDrive.click(); + // TODO: Select target using ENV variable for the drive + const targetVirtualDrive = $('=/dev/disk8'); + await targetVirtualDrive.waitForDisplayed({ timeout: 10000 }); + await targetVirtualDrive.click(); - const validateTargetButton = $('button[data-testid="validate-target-button"]') - await validateTargetButton.waitForClickable({timeout: 10000}) + const validateTargetButton = $( + 'button[data-testid="validate-target-button"]', + ); + await validateTargetButton.waitForClickable({ timeout: 10000 }); await validateTargetButton.click(); - - const flashNowButton= $('button[data-testid="flash-now-button"]') - await flashNowButton.waitForClickable({timeout: 10000}) + + const flashNowButton = $('button[data-testid="flash-now-button"]'); + await flashNowButton.waitForClickable({ timeout: 10000 }); await flashNowButton.click(); - // FIXME: not able to find the flashResults :( - const flashResults = $('span[data-testid="flash-results"]') - await flashResults.waitForDisplayed({timeout: 20000}) - - expect(flashResults.getText()).toBe('Flash Completed!') - - // we're good; - // now we should check the content of the image but we can do that outside wdio + // FIXME: not able to find the flashResults :( + const flashResults = $('span[data-testid="flash-results"]'); + await flashResults.waitForDisplayed({ timeout: 20000 }); + + expect(flashResults.getText()).toBe('Flash Completed!'); + + // we're good; + // now we should check the content of the image but we can do that outside wdio }); }); diff --git a/tests/e2e/e2e-flash-from-url.spec.ts b/tests/e2e/e2e-flash-from-url.spec.ts index 0e1d735fffe..4441ca75ba7 100644 --- a/tests/e2e/e2e-flash-from-url.spec.ts +++ b/tests/e2e/e2e-flash-from-url.spec.ts @@ -5,26 +5,57 @@ describe('Electron Testing', () => { console.log('Hello', await browser.getTitle(), 'application!'); }); - it('should "flash from url"', async () => { - const flashFromUrlButton = $('button[data-testid="flash-from-url"]') - await flashFromUrlButton.waitForDisplayed({timeout: 10000}) + it('should "select an url source"', async () => { + const flashFromUrlButton = $('button[data-testid="flash-from-url"]'); + await flashFromUrlButton.waitForDisplayed({ timeout: 10000 }); // const isDisplayed = await flashFromFileButton.isDisplayed(); await flashFromUrlButton.click(); - const enterValidUrlInput = $('input[data-testid="source-url-input"]') - await enterValidUrlInput.waitForDisplayed({timeout: 10000}) - - // TODO: use an env variable for the URL - await enterValidUrlInput.setValue('https://api.balena-cloud.com/download?deviceType=raspberrypi4-64&version=5.2.8&fileType=.zip&developmentMode=true') + const enterValidUrlInput = $('input[data-testid="source-url-input"]'); + await enterValidUrlInput.waitForDisplayed({ timeout: 10000 }); - // FIXME: this is a workaround for the sidecar to have the time to load in the background - // We have a race condition to fix here - browser.pause(3000); // 3-second delay + // TODO: use an env variable for the URL + await enterValidUrlInput.setValue( + 'https://api.balena-cloud.com/download?deviceType=raspberrypi4-64&version=5.2.8&fileType=.zip&developmentMode=true', + ); - const sourceUrlOkButton = $('button[data-testid="source-url-ok-button"]') - await sourceUrlOkButton.waitForDisplayed({timeout: 10000}) + const sourceUrlOkButton = $('button[data-testid="source-url-ok-button"]'); + await sourceUrlOkButton.waitForDisplayed({ timeout: 10000 }); await sourceUrlOkButton.click(); + }); + + it('should "select a virtual target"', async () => { + const selectTargetButton = $('button[data-testid="select-target-button"]'); + await selectTargetButton.waitForClickable({ timeout: 30000 }); + await selectTargetButton.click(); + + // target drive is set in the github custom test action + // if you run the test locally, pass the varibale + const targetVirtualDrive = $(`=${process.env.TARGET_DRIVE}`); + await targetVirtualDrive.waitForDisplayed({ timeout: 10000 }); + await targetVirtualDrive.click(); + + const validateTargetButton = $( + 'button[data-testid="validate-target-button"]', + ); + await validateTargetButton.waitForClickable({ timeout: 10000 }); + await validateTargetButton.click(); + }); + + it('should "start flashing"', async () => { + const flashNowButton = $('button[data-testid="flash-now-button"]'); + await flashNowButton.waitForClickable({ timeout: 10000 }); + await flashNowButton.click(); + }); + + it('should find "Flash Completed" screen', async () => { + const flashResults = $('[data-testid="flash-results"]'); + await flashResults.waitForDisplayed({ timeout: 180000 }); + + const flashResultsText = await flashResults.getText(); + expect(flashResultsText).toBe('Flash Completed!'); - // we're blocked here because of a bug with URL loading + // we're good; + // now we should check the content of the image but we can do that outside wdio }); }); diff --git a/wdio.conf.ts b/wdio.conf.ts index fbe54f77063..004de7eb65b 100644 --- a/wdio.conf.ts +++ b/wdio.conf.ts @@ -48,8 +48,8 @@ export const config: Options.Testrunner = { suites: { 'e2e': [ - 'tests/e2e/e2e-flash-from-file.spec.ts', - // 'tests/e2e/flash-from-url.spec.ts', + // 'tests/e2e/e2e-flash-from-file.spec.ts', + 'tests/e2e/e2e-flash-from-url.spec.ts', ], }, //