mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 17:32:41 +00:00
smoke - improve app lifecycle (#139693)
* smoke - make sure app is closed when `app.start` fails * smoke - `capturePage` to fallback to active window * smoke - more logging around remote resolving
This commit is contained in:
parent
d89b167121
commit
b2e79a699f
|
@ -66,7 +66,7 @@ export class Driver implements IDriver, IWindowDriverRegistry {
|
|||
async capturePage(windowId: number): Promise<string> {
|
||||
await this.whenUnfrozen(windowId);
|
||||
|
||||
const window = this.windowsMainService.getWindowById(windowId);
|
||||
const window = this.windowsMainService.getWindowById(windowId) ?? this.windowsMainService.getLastActiveWindow(); // fallback to active window to ensure we capture window
|
||||
if (!window?.win) {
|
||||
throw new Error('Invalid window');
|
||||
}
|
||||
|
|
|
@ -109,15 +109,28 @@ export class Application {
|
|||
}
|
||||
|
||||
private async checkWindowReady(code: Code): Promise<any> {
|
||||
this.logger.log('checkWindowReady: begin');
|
||||
|
||||
await code.waitForWindowIds(ids => ids.length > 0);
|
||||
await code.waitForElement('.monaco-workbench');
|
||||
|
||||
if (this.remote) {
|
||||
await code.waitForTextContent('.monaco-workbench .statusbar-item[id="status.host"]', ' TestResolver', undefined, 2000);
|
||||
// Web or remote: wait for a remote connection state change
|
||||
if (this.remote || this.web) {
|
||||
await code.waitForTextContent('.monaco-workbench .statusbar-item[id="status.host"]', undefined, s => {
|
||||
this.logger.log(`checkWindowReady: remote indicator text is ${s}`);
|
||||
|
||||
// The absence of "Opening Remote" is not a strict
|
||||
// indicator for a successful connection, but we
|
||||
// want to avoid hanging here until timeout because
|
||||
// this method is potentially called from a location
|
||||
// that has no tracing enabled making it hard to
|
||||
// diagnose this. As such, as soon as the connection
|
||||
// state changes away from the "Opening Remote..." one
|
||||
// we return.
|
||||
return !s.includes('Opening Remote');
|
||||
}, 300 /* = 30s of retry */);
|
||||
}
|
||||
|
||||
if (this.web) {
|
||||
await code.waitForTextContent('.monaco-workbench .statusbar-item[id="status.host"]', undefined, s => !s.includes('Opening Remote'), 2000);
|
||||
}
|
||||
this.logger.log('checkWindowReady: end');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,8 +290,10 @@ export class Code {
|
|||
|
||||
private async getActiveWindowId(): Promise<number> {
|
||||
if (typeof this._activeWindowId !== 'number') {
|
||||
this.logger.log('getActiveWindowId(): begin');
|
||||
const windows = await this.driver.getWindowIds();
|
||||
this._activeWindowId = windows[0];
|
||||
this.logger.log(`getActiveWindowId(): end (windowId=${this._activeWindowId})`);
|
||||
}
|
||||
|
||||
return this._activeWindowId;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { join } from 'path';
|
||||
import { Application, ApplicationOptions, Logger, Quality } from '../../../../automation';
|
||||
import { getRandomUserDataDir, startApp, timeout, installDiagnosticsHandler, installAppAfterHandler } from '../../utils';
|
||||
import { createApp, timeout, installDiagnosticsHandler, installAppAfterHandler, getRandomUserDataDir } from '../../utils';
|
||||
|
||||
export function setup(ensureStableCode: () => string | undefined, logger: Logger) {
|
||||
describe('Data Loss (insiders -> insiders)', () => {
|
||||
|
@ -17,7 +17,8 @@ export function setup(ensureStableCode: () => string | undefined, logger: Logger
|
|||
installAppAfterHandler(() => app);
|
||||
|
||||
it('verifies opened editors are restored', async function () {
|
||||
app = await startApp(this.defaultOptions);
|
||||
app = createApp(this.defaultOptions);
|
||||
await app.start();
|
||||
|
||||
// Open 3 editors
|
||||
await app.workbench.quickaccess.openFile(join(app.workspacePathOrFolder, 'bin', 'www'));
|
||||
|
@ -38,7 +39,8 @@ export function setup(ensureStableCode: () => string | undefined, logger: Logger
|
|||
});
|
||||
|
||||
it('verifies editors can save and restore', async function () {
|
||||
app = await startApp(this.defaultOptions);
|
||||
app = createApp(this.defaultOptions);
|
||||
await app.start();
|
||||
|
||||
const textToType = 'Hello, Code';
|
||||
|
||||
|
@ -74,7 +76,8 @@ export function setup(ensureStableCode: () => string | undefined, logger: Logger
|
|||
});
|
||||
|
||||
async function testHotExit(restartDelay: number | undefined, autoSave: boolean | undefined) {
|
||||
app = await startApp(this.defaultOptions);
|
||||
app = createApp(this.defaultOptions);
|
||||
await app.start();
|
||||
|
||||
if (autoSave) {
|
||||
await app.workbench.settingsEditor.addUserSetting('files.autoSave', '"afterDelay"');
|
||||
|
@ -129,10 +132,13 @@ export function setup(ensureStableCode: () => string | undefined, logger: Logger
|
|||
this.skip();
|
||||
}
|
||||
|
||||
// On macOS, the stable app fails to launch on first try,
|
||||
// so let's retry this once
|
||||
// https://github.com/microsoft/vscode/pull/127799
|
||||
// macOS: the first launch of stable Code will trigger
|
||||
// additional checks in the OS (notarization validation)
|
||||
// so it can take a very long time. as such we increase
|
||||
// the timeout and install a retry handler to make sure
|
||||
// we do not fail as a consequence.
|
||||
if (process.platform === 'darwin') {
|
||||
this.timeout(2 * 60 * 1000);
|
||||
this.retries(2);
|
||||
}
|
||||
|
||||
|
|
|
@ -311,6 +311,7 @@ async function setup(): Promise<void> {
|
|||
logger.log('Smoketest setup done!\n');
|
||||
}
|
||||
|
||||
// Before main suite (before all tests)
|
||||
before(async function () {
|
||||
this.timeout(2 * 60 * 1000); // allow two minutes for setup
|
||||
|
||||
|
@ -333,6 +334,7 @@ before(async function () {
|
|||
await setup();
|
||||
});
|
||||
|
||||
// After main suite (after all tests)
|
||||
after(async function () {
|
||||
try {
|
||||
let deleted = false;
|
||||
|
|
|
@ -88,7 +88,8 @@ export function installDiagnosticsHandler(logger: Logger, appFn?: () => Applicat
|
|||
|
||||
function installAppBeforeHandler(optionsTransform?: (opts: ApplicationOptions) => ApplicationOptions) {
|
||||
before(async function () {
|
||||
this.app = await startApp(this.defaultOptions, optionsTransform);
|
||||
this.app = createApp(this.defaultOptions, optionsTransform);
|
||||
await this.app.start();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -105,7 +106,7 @@ export function installAppAfterHandler(appFn?: () => Application | undefined, jo
|
|||
});
|
||||
}
|
||||
|
||||
export async function startApp(options: ApplicationOptions, optionsTransform?: (opts: ApplicationOptions) => ApplicationOptions): Promise<Application> {
|
||||
export function createApp(options: ApplicationOptions, optionsTransform?: (opts: ApplicationOptions) => ApplicationOptions): Application {
|
||||
if (optionsTransform) {
|
||||
options = optionsTransform({ ...options });
|
||||
}
|
||||
|
@ -115,8 +116,6 @@ export async function startApp(options: ApplicationOptions, optionsTransform?: (
|
|||
userDataDir: getRandomUserDataDir(options)
|
||||
});
|
||||
|
||||
await app.start();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue