Skip to content

Commit

Permalink
Correct tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fcollonval committed Aug 17, 2021
1 parent c0fd1e1 commit f252d8f
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 25 deletions.
82 changes: 70 additions & 12 deletions galata/src/fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.

import { Session, TerminalAPI } from '@jupyterlab/services';
import { Session, TerminalAPI, Workspace } from '@jupyterlab/services';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import {
test as base,
Expand Down Expand Up @@ -49,11 +49,16 @@ export type GalataOptions = {
*/
serverFiles: 'on' | 'off' | 'only-on-failure';
/**
* Whether to mock JupyterLab state in-memory or not.
* Mock JupyterLab state in-memory or not.
*
* Possible values are:
* - true (default): JupyterLab state will be mocked on a per test basis
* - false: JupyterLab state won't be mocked (Be careful it will write state in local files)
* - Record<string, unknown>: Initial JupyterLab data state - Mapping (state key, value).
*
* By default the state is stored in-memory
*/
mockState: boolean; // TODO allow loading custom state
mockState: boolean | Record<string, unknown>;
/**
* Mock JupyterLab settings in-memory or not.
*
Expand All @@ -65,7 +70,7 @@ export type GalataOptions = {
* By default the settings are stored in-memory. However the
* they are still initialized with the hard drive values.
*/
mockSettings: boolean | Record<string, unknown>; // TODO test mock with record
mockSettings: boolean | Record<string, unknown>;
/**
* Unique test temporary path created on the server.
*
Expand Down Expand Up @@ -95,7 +100,12 @@ export const test: TestType<
await use(baseURL ?? process.env.TARGET_URL ?? 'http://localhost:8888');
},
/**
* Whether to mock JupyterLab state in-memory or not.
* Mock JupyterLab state in-memory or not.
*
* Possible values are:
* - true (default): JupyterLab state will be mocked on a per test basis
* - false: JupyterLab state won't be mocked (Be careful it will write state in local files)
* - Record<string, unknown>: Initial JupyterLab data state - Mapping (state key, value).
*
* By default the state is stored in-memory
*/
Expand All @@ -105,8 +115,8 @@ export const test: TestType<
*
* Possible values are:
* - true (default): JupyterLab settings will be mocked on a per test basis
* - false: JupyterLab settings won't be mocked (Be careful it will read & write settings local files)
* - Record<string, any>: Mapping {pluginId: settings} that will override default settings
* - false: JupyterLab settings won't be mocked (Be careful it may write settings local files)
* - Record<string, unknown>: Mapping {pluginId: settings} that will override default settings
*
* By default the settings are stored in-memory. However the
* they are still initialized with the hard drive values.
Expand Down Expand Up @@ -204,8 +214,14 @@ export const test: TestType<
);
}

const workspace = { data: {}, metadata: {} };
const workspace: Workspace.IWorkspace = {
data: {},
metadata: { id: 'default' }
};
if (mockState) {
if (typeof mockState !== 'boolean') {
workspace.data = { ...mockState } as any;
}
// State will be stored in-memory (after loading the initial version from disk)
await Private.mockState(page, workspace);
}
Expand All @@ -230,7 +246,17 @@ export const test: TestType<
}
});

/**
* Private methods
*/
namespace Private {
/**
* Clear all wanted sessions.
*
* @param baseURL Application base URL
* @param sessions Set of sessions
* @returns Whether the sessions were closed or not
*/
export async function clearSessions(
baseURL: string,
sessions: Set<string>
Expand All @@ -243,6 +269,13 @@ namespace Private {
return responses.every(response => response.ok);
}

/**
* Clear all wanted terminals.
*
* @param baseURL Application base URL
* @param terminals Set of terminals
* @returns Whether the terminals were closed or not
*/
export async function clearTerminals(
baseURL: string,
terminals: Set<string>
Expand All @@ -255,12 +288,15 @@ namespace Private {
return responses.every(response => response.ok);
}

/**
* Mock workspace route.
*
* @param page Page model object
* @param workspace In-memory workspace
*/
export function mockState(
page: Page,
workspace: {
data: Record<string, unknown>;
metadata: Record<string, unknown>;
}
workspace: Workspace.IWorkspace
): Promise<void> {
return page.route(/.*\/api\/workspaces[\/\w+]+/, (route, request) => {
switch (request.method()) {
Expand All @@ -281,8 +317,18 @@ namespace Private {
});
}

/**
* Settings REST API endpoint
*/
const settingsRegex = /.*\/api\/settings(?<id>(\/[@:-\w]+)*)/;

/**
* Mock settings route.
*
* @param page Page model object
* @param settings In-memory settings
* @param mockedSettings Test mocked settings
*/
export function mockSettings(
page: Page,
settings: ISettingRegistry.IPlugin[],
Expand Down Expand Up @@ -388,6 +434,12 @@ namespace Private {
});
}

/**
* Track the sessions created during a test
*
* @param page Page model object
* @param sessions Set of session ids
*/
export function trackSessions(
page: Page,
sessions: Set<string>
Expand Down Expand Up @@ -420,6 +472,12 @@ namespace Private {
});
}

/**
* Track the terminals created during a test
*
* @param page Page model object
* @param terminals Set of terminal names
*/
export function trackTerminals(
page: Page,
terminals: Set<string>
Expand Down
42 changes: 33 additions & 9 deletions galata/src/jupyterlabpage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,15 +490,6 @@ export class JupyterLabPage implements IJupyterLabPage {
if (!jlabAccessible) {
throw new Error('Failed to access JupyterLab object in browser context');
}

// TODO is this still needed?
// let resourcePath = '/lab';
// if (context.jlabWorkspace) {
// resourcePath = `${resourcePath}/workspaces/${context.jlabWorkspace}`;
// }
// await this.page.evaluate(async resourcePath => {
// await window.galataip.waitForLaunch(resourcePath);
// }, resourcePath);
}

/**
Expand Down Expand Up @@ -528,13 +519,22 @@ export class JupyterLabPage implements IJupyterLabPage {
};
}

/**
* Activity helper
*/
class ActivityHelper {
constructor(readonly page: Page) {}

/**
* JupyterLab launcher selector
*/
get launcherSelector(): string {
return Private.xpBuildActivityTabSelector('Launcher');
}

/**
* Close all widgets in the main area
*/
async closeAll(): Promise<void> {
await this.page.evaluate(async (launcherSelector: string) => {
const app = window.jupyterlab;
Expand All @@ -544,6 +544,12 @@ class ActivityHelper {
}, this.launcherSelector);
}

/**
* Whether a tab is active or not
*
* @param name Activity name
* @returns Active status
*/
async isTabActive(name: string): Promise<boolean> {
const tab = await this.getTab(name);
return (
Expand All @@ -555,6 +561,12 @@ class ActivityHelper {
);
}

/**
* Get a handle on a tab
*
* @param name Activity name
* @returns Handle on the tab or null if the tab is not found
*/
getTab(name?: string): Promise<ElementHandle<Element> | null> {
const page = this.page;
const tabSelector = name
Expand All @@ -563,6 +575,12 @@ class ActivityHelper {
return page.$(`xpath=${tabSelector}`);
}

/**
* Get a handle on a panel
*
* @param name Activity name
* @returns Handle on the tab or null if the tab is not found
*/
async getPanel(name?: string): Promise<ElementHandle<Element> | null> {
const page = this.page;
const tab = await this.getTab(name);
Expand All @@ -576,6 +594,12 @@ class ActivityHelper {
return null;
}

/**
* Activate a tab is active
*
* @param name Activity name
* @returns Whether the action is successful
*/
async activateTab(name: string): Promise<boolean> {
const tab = await this.getTab(name);
if (tab) {
Expand Down
52 changes: 49 additions & 3 deletions galata/test/fixture.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ test.describe('page', () => {

test.describe('tmpPath', () => {
test('should return an unique test folder', ({ tmpPath }) => {
expect(tmpPath).toEqual(
'test-fixture-tmpPath-should-return-an-unique-test-folder'
);
expect(tmpPath).toEqual('test-fixture-should-return-an-unique-test-folder');
});
});

Expand Down Expand Up @@ -53,3 +51,51 @@ test.describe('mockSettings', () => {
expect(await page.theme.getTheme()).toEqual('JupyterLab Light');
});
});

test.describe('mockState', () => {
// Use non-default state to have the running session panel displayed
test.use({
mockState: {
'layout-restorer:data': {
main: {
dock: {
type: 'tab-area',
currentIndex: 0,
widgets: []
}
},
down: {
size: 0,
widgets: []
},
left: {
collapsed: false,
visible: true,
current: 'running-sessions',
widgets: [
'filebrowser',
'jp-property-inspector',
'running-sessions',
'@jupyterlab/toc:plugin',
'debugger-sidebar',
'extensionmanager.main-view'
]
},
right: {
collapsed: true,
visible: true,
widgets: []
},
relativeSizes: [0.4, 0.6, 0]
}
} as any
});

test('should return the mocked state', async ({ page }) => {
expect(
await page.waitForSelector(
'[aria-label="Running Sessions section"] >> text=OPEN TABS'
)
).toBeTruthy();
});
});
2 changes: 1 addition & 1 deletion galata/test/jupyterlabpage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ playwrightTest('should not be loading galata helper', async ({ page }) => {
// eslint-disable-next-line jest/no-standalone-expect
expect(page['notebook']).toBeUndefined(); // no helper
// eslint-disable-next-line jest/no-standalone-expect
expect(page.url()).toEqual('');
expect(page.url()).toEqual('about:blank');
});
Binary file modified galata/test/notebook.spec.ts-snapshots/code-cell-linux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified galata/test/notebook.spec.ts-snapshots/example-run-linux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified galata/test/notebook.spec.ts-snapshots/markdown-cell-linux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified galata/test/notebook.spec.ts-snapshots/raw-cell-linux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified galata/test/notebook.spec.ts-snapshots/run-cells-linux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f252d8f

Please sign in to comment.