Path: blob/main/test/smoke/src/areas/workbench/data-loss.test.ts
5267 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { join } from 'path';6import { Application, ApplicationOptions, Logger, Quality } from '../../../../automation';7import { createApp, timeout, installDiagnosticsHandler, installAppAfterHandler, getRandomUserDataDir, suiteLogsPath, suiteCrashPath } from '../../utils';89export function setup(ensureStableCode: () => { stableCodePath: string | undefined; stableCodeVersion: { major: number; minor: number; patch: number } | undefined }, logger: Logger) {10describe('Data Loss (insiders -> insiders)', function () {1112// Double the timeout since these tests involve 2 startups13this.timeout(4 * 60 * 1000);1415let app: Application | undefined = undefined;1617// Shared before/after handling18installDiagnosticsHandler(logger, () => app);19installAppAfterHandler(() => app);2021it('verifies opened editors are restored', async function () {22app = createApp({23...this.defaultOptions,24logsPath: suiteLogsPath(this.defaultOptions, 'test_verifies_opened_editors_are_restored'),25crashesPath: suiteCrashPath(this.defaultOptions, 'test_verifies_opened_editors_are_restored')26});27await app.start();282930// Open 3 editors31await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'bin', 'www'));32await app.workbench.quickaccess.runCommand('View: Keep Editor');33await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'app.js'));34await app.workbench.quickaccess.runCommand('View: Keep Editor');35await app.workbench.editors.newUntitledFile();3637await app.restart();3839// Verify 3 editors are open40await app.workbench.editors.selectTab('Untitled-1');41await app.workbench.editors.selectTab('app.js');42await app.workbench.editors.selectTab('www');4344await app.stop();45app = undefined;46});4748it('verifies editors can save and restore', async function () {49app = createApp({50...this.defaultOptions,51logsPath: suiteLogsPath(this.defaultOptions, 'test_verifies_editors_can_save_and_restore'),52crashesPath: suiteCrashPath(this.defaultOptions, 'test_verifies_editors_can_save_and_restore')53});54await app.start();5556const textToType = 'Hello, Code';5758// open editor and type59await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'app.js'));60await app.workbench.editor.waitForTypeInEditor('app.js', textToType);61await app.workbench.editors.waitForTab('app.js', true);6263// save64await app.workbench.editors.saveOpenedFile();65await app.workbench.editors.waitForTab('app.js', false);6667// restart68await app.restart();6970// verify contents71await app.workbench.editor.waitForEditorContents('app.js', contents => contents.indexOf(textToType) > -1);7273await app.stop();74app = undefined;75});7677it('verifies that "hot exit" works for dirty files (without delay)', function () {78return testHotExit.call(this, 'test_verifies_that_hot_exit_works_for_dirty_files_without_delay', undefined, undefined);79});8081it('verifies that "hot exit" works for dirty files (with delay)', function () {82return testHotExit.call(this, 'test_verifies_that_hot_exit_works_for_dirty_files_with_delay', 2000, undefined);83});8485it('verifies that auto save triggers on shutdown', function () {86return testHotExit.call(this, 'test_verifies_that_auto_save_triggers_on_shutdown', undefined, true);87});8889async function testHotExit(this: import('mocha').Context, title: string, restartDelay: number | undefined, autoSave: boolean | undefined) {90app = createApp({91...this.defaultOptions,92logsPath: suiteLogsPath(this.defaultOptions, title),93crashesPath: suiteCrashPath(this.defaultOptions, title)94});95await app.start();9697if (autoSave) {98await app.workbench.settingsEditor.addUserSetting('files.autoSave', '"afterDelay"');99}100101const textToTypeInUntitled = 'Hello from Untitled';102103await app.workbench.editors.newUntitledFile();104await app.workbench.editor.waitForTypeInEditor('Untitled-1', textToTypeInUntitled);105await app.workbench.editors.waitForTab('Untitled-1', true);106107const textToType = 'Hello, Code';108await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'readme.md'));109await app.workbench.editor.waitForTypeInEditor('readme.md', textToType);110await app.workbench.editors.waitForTab('readme.md', !autoSave);111112if (typeof restartDelay === 'number') {113// this is an OK use of a timeout in a smoke test:114// we want to simulate a user having typed into115// the editor and pausing for a moment before116// terminating117await timeout(restartDelay);118}119120await app.restart();121122await app.workbench.editors.waitForTab('readme.md', !autoSave);123await app.workbench.editors.waitForTab('Untitled-1', true);124125await app.workbench.editors.selectTab('readme.md');126await app.workbench.editor.waitForEditorContents('readme.md', contents => contents.indexOf(textToType) > -1);127128await app.workbench.editors.selectTab('Untitled-1');129await app.workbench.editor.waitForEditorContents('Untitled-1', contents => contents.indexOf(textToTypeInUntitled) > -1);130131await app.stop();132app = undefined;133}134});135136describe('Data Loss (stable -> insiders)', function () {137138// Double the timeout since these tests involve 2 startups139this.timeout(4 * 60 * 1000);140141let insidersApp: Application | undefined = undefined;142let stableApp: Application | undefined = undefined;143144// Shared before/after handling145installDiagnosticsHandler(logger, () => insidersApp ?? stableApp);146installAppAfterHandler(() => insidersApp ?? stableApp, async () => stableApp?.stop());147148it('verifies opened editors are restored', async function () {149const { stableCodePath, stableCodeVersion } = ensureStableCode();150if (!stableCodePath) {151this.skip();152}153154// macOS: the first launch of stable Code will trigger155// additional checks in the OS (notarization validation)156// so it can take a very long time. as such we install157// a retry handler to make sure we do not fail as a158// consequence.159if (process.platform === 'darwin') {160this.retries(2);161}162163const userDataDir = getRandomUserDataDir(this.defaultOptions.userDataDir);164const logsPath = suiteLogsPath(this.defaultOptions, 'test_verifies_opened_editors_are_restored_from_stable');165const crashesPath = suiteCrashPath(this.defaultOptions, 'test_verifies_opened_editors_are_restored_from_stable');166167const stableOptions: ApplicationOptions = Object.assign({}, this.defaultOptions);168stableOptions.codePath = stableCodePath;169stableOptions.userDataDir = userDataDir;170stableOptions.quality = Quality.Stable;171stableOptions.logsPath = logsPath;172stableOptions.crashesPath = crashesPath;173stableOptions.version = stableCodeVersion ?? { major: 0, minor: 0, patch: 0 };174175stableApp = new Application(stableOptions);176await stableApp.start();177178// Open 3 editors179await stableApp.workbench.quickaccess.openFile(join(stableApp.workspacePathOrFolder, 'bin', 'www'));180await stableApp.workbench.quickaccess.runCommand('View: Keep Editor');181await stableApp.workbench.quickaccess.openFile(join(stableApp.workspacePathOrFolder, 'app.js'));182await stableApp.workbench.quickaccess.runCommand('View: Keep Editor');183await stableApp.workbench.editors.newUntitledFile();184185await stableApp.stop();186stableApp = undefined;187188const insiderOptions: ApplicationOptions = Object.assign({}, this.defaultOptions);189insiderOptions.userDataDir = userDataDir;190insiderOptions.logsPath = logsPath;191insiderOptions.crashesPath = crashesPath;192193insidersApp = new Application(insiderOptions);194await insidersApp.start();195196// Verify 3 editors are open197await insidersApp.workbench.editors.selectTab('Untitled-1');198await insidersApp.workbench.editors.selectTab('app.js');199await insidersApp.workbench.editors.selectTab('www');200201await insidersApp.stop();202insidersApp = undefined;203});204205it('verifies that "hot exit" works for dirty files (without delay)', async function () {206return testHotExit.call(this, `test_verifies_that_hot_exit_works_for_dirty_files_without_delay_from_stable`, undefined);207});208209it('verifies that "hot exit" works for dirty files (with delay)', async function () {210return testHotExit.call(this, `test_verifies_that_hot_exit_works_for_dirty_files_with_delay_from_stable`, 2000);211});212213async function testHotExit(this: import('mocha').Context, title: string, restartDelay: number | undefined) {214const { stableCodePath, stableCodeVersion } = ensureStableCode();215if (!stableCodePath) {216this.skip();217}218219const userDataDir = getRandomUserDataDir(this.defaultOptions.userDataDir);220const logsPath = suiteLogsPath(this.defaultOptions, title);221const crashesPath = suiteCrashPath(this.defaultOptions, title);222223const stableOptions: ApplicationOptions = Object.assign({}, this.defaultOptions);224stableOptions.codePath = stableCodePath;225stableOptions.userDataDir = userDataDir;226stableOptions.quality = Quality.Stable;227stableOptions.logsPath = logsPath;228stableOptions.crashesPath = crashesPath;229stableOptions.version = stableCodeVersion ?? { major: 0, minor: 0, patch: 0 };230231stableApp = new Application(stableOptions);232await stableApp.start();233234const textToTypeInUntitled = 'Hello from Untitled';235236await stableApp.workbench.editors.newUntitledFile();237await stableApp.workbench.editor.waitForTypeInEditor('Untitled-1', textToTypeInUntitled);238await stableApp.workbench.editors.waitForTab('Untitled-1', true);239240const textToType = 'Hello, Code';241await stableApp.workbench.quickaccess.openFile(join(stableApp.workspacePathOrFolder, 'readme.md'));242await stableApp.workbench.editor.waitForTypeInEditor('readme.md', textToType);243await stableApp.workbench.editors.waitForTab('readme.md', true);244245if (typeof restartDelay === 'number') {246// this is an OK use of a timeout in a smoke test247// we want to simulate a user having typed into248// the editor and pausing for a moment before249// terminating250await timeout(restartDelay);251}252253await stableApp.stop();254stableApp = undefined;255256const insiderOptions: ApplicationOptions = Object.assign({}, this.defaultOptions);257insiderOptions.userDataDir = userDataDir;258insiderOptions.logsPath = logsPath;259insiderOptions.crashesPath = crashesPath;260261insidersApp = new Application(insiderOptions);262await insidersApp.start();263264await insidersApp.workbench.editors.waitForTab('readme.md', true);265await insidersApp.workbench.editors.waitForTab('Untitled-1', true);266267await insidersApp.workbench.editors.selectTab('readme.md');268await insidersApp.workbench.editor.waitForEditorContents('readme.md', contents => contents.indexOf(textToType) > -1);269270await insidersApp.workbench.editors.selectTab('Untitled-1');271await insidersApp.workbench.editor.waitForEditorContents('Untitled-1', contents => contents.indexOf(textToTypeInUntitled) > -1);272273await insidersApp.stop();274insidersApp = undefined;275}276});277}278279280