diff --git a/packages/browsers/src/install.ts b/packages/browsers/src/install.ts index 098a99f0078..6d607fcd0d2 100644 --- a/packages/browsers/src/install.ts +++ b/packages/browsers/src/install.ts @@ -140,15 +140,22 @@ export async function install( options.platform, options.buildId ); - if (existsSync(outputPath)) { - return new InstalledBrowser( - cache, - options.browser, - options.buildId, - options.platform - ); - } + try { + if (existsSync(outputPath)) { + const installedBrowser = new InstalledBrowser( + cache, + options.browser, + options.buildId, + options.platform + ); + if (!existsSync(installedBrowser.executablePath)) { + throw new Error( + `The browser folder (${outputPath}) exists but the executable (${installedBrowser.executablePath}) is missing` + ); + } + return installedBrowser; + } debugInstall(`Downloading binary from ${url}`); try { debugTime('download'); diff --git a/packages/browsers/test/src/chrome/install.spec.ts b/packages/browsers/test/src/chrome/install.spec.ts index a4a90c5d531..83d039ab84a 100644 --- a/packages/browsers/test/src/chrome/install.spec.ts +++ b/packages/browsers/test/src/chrome/install.spec.ts @@ -63,6 +63,35 @@ describe('Chrome install', () => { ); }); + it('can detect missing executables', async function () { + this.timeout(60000); + const expectedOutputPath = path.join( + tmpDir, + 'chrome', + `${BrowserPlatform.LINUX}-${testChromeBuildId}` + ); + fs.mkdirSync(expectedOutputPath, {recursive: true}); + assert.strictEqual(fs.existsSync(expectedOutputPath), true); + async function installThatThrows(): Promise { + try { + await install({ + cacheDir: tmpDir, + browser: Browser.CHROME, + platform: BrowserPlatform.LINUX, + buildId: testChromeBuildId, + }); + return undefined; + } catch (err) { + return err as Error; + } + } + assert.strictEqual( + (await installThatThrows())?.message, + `The browser folder (${expectedOutputPath}) exists but the executable (${expectedOutputPath}/chrome-linux64/chrome) is missing` + ); + assert.strictEqual(fs.existsSync(expectedOutputPath), true); + }); + it('should download a buildId that is a zip archive', async function () { this.timeout(60000); const expectedOutputPath = path.join(