-
Notifications
You must be signed in to change notification settings - Fork 245
feat(smoke-tests): test updating from the latest release to the newly packaged app COMPASS-8532 COMPASS-8535 #6669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
28bbb85
4074347
3c7162d
1ec2465
a897d93
1c90eba
76b2984
1011053
56d0879
9bd0524
21efcb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,66 +13,71 @@ function wait(ms: number) { | |
| } | ||
|
|
||
| describe('Auto-update', function () { | ||
| it('auto-update from', async function () { | ||
| if (process.env.TEST_NAME !== 'auto-update-from') { | ||
| // we don't want this test to execute along with all the others under | ||
| // normal circumstances because it is destructive - it overwrites Compass | ||
| // itself | ||
| this.skip(); | ||
| } | ||
|
|
||
| // run the app and wait for it to auto-update | ||
| console.log('starting compass the first time'); | ||
| const compass = await init('auto-update from', { firstRun: true }); | ||
| const { browser } = compass; | ||
| try { | ||
| await browser.$(Selectors.AutoUpdateToast).waitForDisplayed(); | ||
|
|
||
| if (process.env.AUTO_UPDATE_UPDATABLE === 'true') { | ||
| const restartButton = browser.$(Selectors.AutoUpdateRestartButton); | ||
| await restartButton.waitForDisplayed(); | ||
|
|
||
| // We could click the restart button to apply the update and restart the | ||
| // app, but restarting the app confuses webdriverio or at least our test | ||
| // helpers. So we're going to just restart the app manually. | ||
| await browser.pause(1000); | ||
| } else { | ||
| // When auto-update is not supported the toast contains a link to | ||
| // download | ||
| const linkElement = browser.$(Selectors.AutoUpdateDownloadLink); | ||
| await linkElement.waitForDisplayed(); | ||
| expect(await linkElement.getAttribute('href')).to.equal( | ||
| 'https://www.mongodb.com/try/download/compass?utm_source=compass&utm_medium=product' | ||
| ); | ||
| for (const testName of ['auto-update-from', 'auto-update-to']) { | ||
| it(testName, async function () { | ||
| if (process.env.TEST_NAME !== testName) { | ||
| // we don't want this test to execute along with all the others under | ||
| // normal circumstances because it is destructive - it overwrites Compass | ||
| // itself | ||
| this.skip(); | ||
| } | ||
| } finally { | ||
| await browser.screenshot(screenshotPathName('auto-update-from')); | ||
| await cleanup(compass); | ||
| } | ||
|
|
||
| if (process.env.AUTO_UPDATE_UPDATABLE === 'true') { | ||
| console.log( | ||
| 'pause to make sure the app properly exited before starting again' | ||
| ); | ||
| await wait(10_000); | ||
|
|
||
| console.log('starting compass a second time'); | ||
| // run the app again and check that the version changed | ||
| const compass = await init('auto-update from restart', { | ||
| firstRun: false, | ||
| }); | ||
| // run the app and wait for it to auto-update | ||
| console.log('starting compass the first time'); | ||
| const compass = await init(testName, { firstRun: true }); | ||
| const { browser } = compass; | ||
| try { | ||
| await browser.$(Selectors.AutoUpdateToast).waitForDisplayed(); | ||
| await browser | ||
| .$(Selectors.AutoUpdateReleaseNotesLink) | ||
| .waitForDisplayed(); | ||
|
|
||
| if (process.env.AUTO_UPDATE_UPDATABLE === 'true') { | ||
| const restartButton = browser.$(Selectors.AutoUpdateRestartButton); | ||
| await restartButton.waitForDisplayed(); | ||
|
|
||
| // We could click the restart button to apply the update and restart the | ||
| // app, but restarting the app confuses webdriverio or at least our test | ||
| // helpers. So we're going to just restart the app manually. | ||
| await browser.pause(1000); | ||
| } else { | ||
| // When auto-update is not supported the toast contains a link to | ||
| // download | ||
| const linkElement = browser.$(Selectors.AutoUpdateDownloadLink); | ||
| await linkElement.waitForDisplayed(); | ||
| expect(await linkElement.getAttribute('href')).to.equal( | ||
| 'https://www.mongodb.com/try/download/compass?utm_source=compass&utm_medium=product' | ||
| ); | ||
|
|
||
| // TODO: when updating to a known version we know the version, so | ||
| // check for the text | ||
| } | ||
| } finally { | ||
| await browser.screenshot( | ||
| screenshotPathName('auto-update-from-restart') | ||
| ); | ||
| await browser.screenshot(screenshotPathName(testName)); | ||
| await cleanup(compass); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| if (process.env.AUTO_UPDATE_UPDATABLE === 'true') { | ||
| console.log( | ||
| 'pause to make sure the app properly exited before starting again' | ||
| ); | ||
| await wait(10_000); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we poll the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, but where do we get the pid? I think we can clean it up but in an effort to get somewhere let's do that as a follow-up. |
||
|
|
||
| console.log('starting compass a second time'); | ||
| // run the app again and check that the version changed | ||
| const compass = await init(`${testName} restart`, { | ||
| firstRun: false, | ||
| }); | ||
| const { browser } = compass; | ||
| try { | ||
| await browser.$(Selectors.AutoUpdateToast).waitForDisplayed(); | ||
| await browser | ||
| .$(Selectors.AutoUpdateReleaseNotesLink) | ||
| .waitForDisplayed(); | ||
| // TODO: when updating to a known version we know the version, so | ||
lerouxb marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // check for the text | ||
| } finally { | ||
| await browser.screenshot(screenshotPathName(`${testName}-restart`)); | ||
| await cleanup(compass); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,12 +2,10 @@ | |
| import assert from 'node:assert/strict'; | ||
| import fs from 'node:fs'; | ||
| import path from 'node:path'; | ||
| import { once } from 'node:events'; | ||
|
|
||
| import yargs from 'yargs'; | ||
| import { hideBin } from 'yargs/helpers'; | ||
| import { pick } from 'lodash'; | ||
| import { execute, executeAsync } from './execute'; | ||
| import { | ||
| type PackageDetails, | ||
| readPackageDetails, | ||
|
|
@@ -16,18 +14,22 @@ import { | |
| import { createSandbox } from './directories'; | ||
| import { downloadFile } from './downloads'; | ||
| import { type PackageKind, SUPPORTED_PACKAGES } from './packages'; | ||
| import { getLatestRelease } from './releases'; | ||
| import { SUPPORTED_TESTS } from './tests/types'; | ||
| import { type SmokeTestsContext } from './context'; | ||
|
|
||
| import { installMacDMG } from './installers/mac-dmg'; | ||
| import { installMacZIP } from './installers/mac-zip'; | ||
| import { installWindowsZIP } from './installers/windows-zip'; | ||
| import { installWindowsMSI } from './installers/windows-msi'; | ||
|
|
||
| import { testTimeToFirstQuery } from './tests/time-to-first-query'; | ||
| import { testAutoUpdateFrom } from './tests/auto-update-from'; | ||
| import { testAutoUpdateTo } from './tests/auto-update-to'; | ||
|
|
||
| const SUPPORTED_PLATFORMS = ['win32', 'darwin', 'linux'] as const; | ||
| const SUPPORTED_ARCHS = ['x64', 'arm64'] as const; | ||
|
|
||
| const SUPPORTED_TESTS = ['time-to-first-query', 'auto-update-from'] as const; | ||
|
|
||
| function isSupportedPlatform( | ||
| value: unknown | ||
| ): value is typeof SUPPORTED_PLATFORMS[number] { | ||
|
|
@@ -198,9 +200,13 @@ async function run() { | |
| ]) | ||
| ); | ||
|
|
||
| const { kind, appName, filepath, autoUpdatable } = await getTestSubject( | ||
| context | ||
| ); | ||
| const { | ||
| kind, | ||
| appName, | ||
| filepath, | ||
| buildInfo: { channel, version }, | ||
| autoUpdatable, | ||
| } = await getTestSubject(context); | ||
| const install = getInstaller(kind); | ||
|
|
||
| try { | ||
|
|
@@ -209,27 +215,51 @@ async function run() { | |
| } | ||
|
|
||
| for (const testName of context.tests) { | ||
| const installerPath = | ||
| testName === 'auto-update-to' | ||
| ? await getLatestRelease( | ||
| channel, | ||
| context.arch, | ||
| kind, | ||
| context.forceDownload | ||
| ) | ||
| : filepath; | ||
|
||
|
|
||
| const { appPath, uninstall } = install({ | ||
| appName, | ||
| filepath, | ||
| filepath: installerPath, | ||
| destinationPath: context.sandboxPath, | ||
| }); | ||
|
|
||
| try { | ||
| if (testName === 'time-to-first-query') { | ||
| // Auto-update does not work on mac in CI at the moment. So in that case | ||
| // we just run the E2E tests to make sure the app at least starts up. | ||
| runTimeToFirstQuery({ | ||
| testTimeToFirstQuery({ | ||
| appName, | ||
| appPath, | ||
| }); | ||
| } | ||
| if (testName === 'auto-update-from') { | ||
| await runUpdateTest({ | ||
| await testAutoUpdateFrom({ | ||
| appName, | ||
| appPath, | ||
| autoUpdatable, | ||
| }); | ||
| } | ||
| if (testName === 'auto-update-to') { | ||
| assert( | ||
| context.bucketKeyPrefix !== undefined, | ||
| 'Bucket key prefix is needed to download' | ||
| ); | ||
|
|
||
| await testAutoUpdateTo({ | ||
| appName, | ||
| appPath, | ||
| autoUpdatable, | ||
| testName, | ||
| channel, | ||
| bucketKeyPrefix: context.bucketKeyPrefix, | ||
| version, | ||
| }); | ||
| } | ||
| } finally { | ||
|
|
@@ -246,110 +276,6 @@ async function run() { | |
| } | ||
| } | ||
|
|
||
| async function importUpdateServer() { | ||
| try { | ||
| return (await import('compass-mongodb-com')).default; | ||
| } catch (err: unknown) { | ||
| console.log('Remember to npm link compass-mongodb-com'); | ||
| throw err; | ||
| } | ||
| } | ||
|
|
||
| async function startAutoUpdateServer() { | ||
| console.log('Starting auto-update server'); | ||
| const { httpServer, updateChecker, start } = (await importUpdateServer())(); | ||
| start(); | ||
| await once(updateChecker, 'refreshed'); | ||
|
|
||
| return httpServer; | ||
| } | ||
|
|
||
| type RunE2ETestOptions = { | ||
| appName: string; | ||
| appPath: string; | ||
| }; | ||
|
|
||
| function runTimeToFirstQuery({ appName, appPath }: RunE2ETestOptions) { | ||
| execute( | ||
| 'npm', | ||
| [ | ||
| 'run', | ||
| '--unsafe-perm', | ||
| 'test-packaged', | ||
| '--workspace', | ||
| 'compass-e2e-tests', | ||
| '--', | ||
| '--test-filter=time-to-first-query', | ||
| ], | ||
| { | ||
| // We need to use a shell to get environment variables setup correctly | ||
| shell: true, | ||
| env: { | ||
| ...process.env, | ||
| COMPASS_APP_NAME: appName, | ||
| COMPASS_APP_PATH: appPath, | ||
| }, | ||
| } | ||
| ); | ||
| } | ||
|
|
||
| type RunUpdateTestOptions = { | ||
| appName: string; | ||
| appPath: string; | ||
| autoUpdatable?: boolean; | ||
| testName: string; | ||
| }; | ||
|
|
||
| async function runUpdateTest({ | ||
| appName, | ||
| appPath, | ||
| autoUpdatable, | ||
| testName, | ||
| }: RunUpdateTestOptions) { | ||
| process.env.PORT = '0'; // dynamic port | ||
| process.env.UPDATE_CHECKER_ALLOW_DOWNGRADES = 'true'; | ||
|
|
||
| const server = await startAutoUpdateServer(); | ||
|
|
||
| const address = server.address(); | ||
| assert(typeof address === 'object' && address !== null); | ||
| const port = address.port; | ||
| const HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE = `http://localhost:${port}`; | ||
| console.log({ HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE }); | ||
|
|
||
| try { | ||
| // must be async because the update server is running in the same process | ||
| await executeAsync( | ||
| 'npm', | ||
| [ | ||
| 'run', | ||
| '--unsafe-perm', | ||
| 'test-packaged', | ||
| '--workspace', | ||
| 'compass-e2e-tests', | ||
| '--', | ||
| '--test-filter=auto-update', | ||
| ], | ||
| { | ||
| // We need to use a shell to get environment variables setup correctly | ||
| shell: true, | ||
| env: { | ||
| ...process.env, | ||
| HADRON_AUTO_UPDATE_ENDPOINT_OVERRIDE, | ||
| AUTO_UPDATE_UPDATABLE: (!!autoUpdatable).toString(), | ||
| TEST_NAME: testName, | ||
| COMPASS_APP_NAME: appName, | ||
| COMPASS_APP_PATH: appPath, | ||
| }, | ||
| } | ||
| ); | ||
| } finally { | ||
| console.log('Stopping auto-update server'); | ||
| server.close(); | ||
| delete process.env.UPDATE_CHECKER_ALLOW_DOWNGRADES; | ||
| } | ||
| } | ||
|
|
||
| run() | ||
| .then(function () { | ||
| console.log('done'); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.