@jupyterlab/galata 5.0.0-alpha.2 → 5.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +192 -31
  2. package/lib/benchmarkReporter.d.ts +1 -0
  3. package/lib/benchmarkReporter.js +34 -39
  4. package/lib/benchmarkReporter.js.map +1 -1
  5. package/lib/benchmarkVLTpl.js +19 -5
  6. package/lib/benchmarkVLTpl.js.map +1 -1
  7. package/lib/contents.d.ts +5 -5
  8. package/lib/contents.js +32 -36
  9. package/lib/contents.js.map +1 -1
  10. package/lib/extension/global.d.ts +197 -0
  11. package/lib/extension/global.js +601 -0
  12. package/lib/extension/global.js.map +1 -0
  13. package/lib/extension/index.d.ts +6 -0
  14. package/lib/extension/index.js +27 -0
  15. package/lib/extension/index.js.map +1 -0
  16. package/lib/extension/tokens.d.ts +232 -0
  17. package/lib/extension/tokens.js +13 -0
  18. package/lib/extension/tokens.js.map +1 -0
  19. package/lib/extension.d.ts +223 -0
  20. package/lib/{global.js → extension.js} +1 -2
  21. package/lib/extension.js.map +1 -0
  22. package/lib/fixtures.d.ts +32 -10
  23. package/lib/fixtures.js +64 -17
  24. package/lib/fixtures.js.map +1 -1
  25. package/lib/galata.d.ts +140 -19
  26. package/lib/galata.js +272 -87
  27. package/lib/galata.js.map +1 -1
  28. package/lib/helpers/activity.d.ts +6 -0
  29. package/lib/helpers/activity.js +19 -5
  30. package/lib/helpers/activity.js.map +1 -1
  31. package/lib/helpers/debuggerpanel.d.ts +4 -0
  32. package/lib/helpers/debuggerpanel.js +16 -0
  33. package/lib/helpers/debuggerpanel.js.map +1 -1
  34. package/lib/helpers/filebrowser.js +8 -2
  35. package/lib/helpers/filebrowser.js.map +1 -1
  36. package/lib/helpers/index.d.ts +1 -0
  37. package/lib/helpers/index.js +6 -1
  38. package/lib/helpers/index.js.map +1 -1
  39. package/lib/helpers/kernel.js +7 -7
  40. package/lib/helpers/kernel.js.map +1 -1
  41. package/lib/helpers/menu.d.ts +7 -0
  42. package/lib/helpers/menu.js +17 -1
  43. package/lib/helpers/menu.js.map +1 -1
  44. package/lib/helpers/notebook.d.ts +6 -4
  45. package/lib/helpers/notebook.js +127 -31
  46. package/lib/helpers/notebook.js.map +1 -1
  47. package/lib/helpers/sidebar.d.ts +8 -1
  48. package/lib/helpers/sidebar.js +33 -15
  49. package/lib/helpers/sidebar.js.map +1 -1
  50. package/lib/helpers/statusbar.js +1 -1
  51. package/lib/helpers/statusbar.js.map +1 -1
  52. package/lib/helpers/style.d.ts +42 -0
  53. package/lib/helpers/style.js +50 -0
  54. package/lib/helpers/style.js.map +1 -0
  55. package/lib/helpers/theme.js +1 -1
  56. package/lib/helpers/theme.js.map +1 -1
  57. package/lib/index.d.ts +5 -2
  58. package/lib/index.js +12 -3
  59. package/lib/index.js.map +1 -1
  60. package/lib/jupyterlabpage.d.ts +29 -4
  61. package/lib/jupyterlabpage.js +38 -22
  62. package/lib/jupyterlabpage.js.map +1 -1
  63. package/lib/playwright-config.js +5 -1
  64. package/lib/playwright-config.js.map +1 -1
  65. package/lib/utils.js +5 -1
  66. package/lib/utils.js.map +1 -1
  67. package/package.json +31 -47
  68. package/src/benchmarkReporter.ts +756 -0
  69. package/src/benchmarkVLTpl.ts +91 -0
  70. package/src/contents.ts +472 -0
  71. package/src/extension.ts +281 -0
  72. package/src/fixtures.ts +387 -0
  73. package/src/galata.ts +1035 -0
  74. package/src/helpers/activity.ts +115 -0
  75. package/src/helpers/debuggerpanel.ts +159 -0
  76. package/src/helpers/filebrowser.ts +228 -0
  77. package/src/helpers/index.ts +15 -0
  78. package/src/helpers/kernel.ts +39 -0
  79. package/src/helpers/logconsole.ts +32 -0
  80. package/src/helpers/menu.ts +228 -0
  81. package/src/helpers/notebook.ts +1217 -0
  82. package/src/helpers/performance.ts +57 -0
  83. package/src/helpers/sidebar.ts +289 -0
  84. package/src/helpers/statusbar.ts +56 -0
  85. package/src/helpers/style.ts +100 -0
  86. package/src/helpers/theme.ts +50 -0
  87. package/src/index.ts +19 -0
  88. package/src/jupyterlabpage.ts +704 -0
  89. package/src/playwright-config.ts +26 -0
  90. package/src/utils.ts +264 -0
  91. package/src/vega-statistics.d.ts +15 -0
  92. package/lib/global.d.ts +0 -23
  93. package/lib/global.js.map +0 -1
  94. package/lib/inpage/tokens.d.ts +0 -135
  95. package/lib/inpage/tokens.js +0 -9
  96. package/lib/inpage/tokens.js.map +0 -1
  97. package/lib/lib-inpage/inpage.js +0 -3957
  98. package/lib/lib-inpage/inpage.js.map +0 -1
  99. package/style/index.css +0 -10
  100. package/style/index.js +0 -10
@@ -0,0 +1,26 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+
4
+ import { PlaywrightTestConfig } from '@playwright/test';
5
+
6
+ // Default Playwright configuration for JupyterLab
7
+ module.exports = {
8
+ reporter: [
9
+ [process.env.CI ? 'github' : 'list'],
10
+ ['html', { open: process.env.CI ? 'never' : 'on-failure' }]
11
+ ],
12
+ reportSlowTests: null,
13
+ timeout: 60000,
14
+ use: {
15
+ // Browser options
16
+ // headless: false,
17
+ // slowMo: 500,
18
+
19
+ // Context options
20
+ viewport: { width: 1024, height: 768 },
21
+
22
+ // Artifacts
23
+ // trace: 'on-first-retry',
24
+ video: 'retain-on-failure'
25
+ }
26
+ } as PlaywrightTestConfig;
package/src/utils.ts ADDED
@@ -0,0 +1,264 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+
4
+ import { URLExt } from '@jupyterlab/coreutils';
5
+ import { ElementHandle, Page } from '@playwright/test';
6
+ import * as fs from 'fs-extra';
7
+ import * as path from 'path';
8
+
9
+ /**
10
+ * Read a file as a base-64 string
11
+ *
12
+ * @param filePath Local file path
13
+ * @returns Base 64 encoded file content
14
+ */
15
+ export function base64EncodeFile(filePath: string): string {
16
+ const content = fs.readFileSync(filePath);
17
+ return content.toString('base64');
18
+ }
19
+
20
+ /**
21
+ * Private page config data for the Jupyter application.
22
+ */
23
+ let configData: { [key: string]: string } | null = null;
24
+
25
+ // Get config data
26
+ async function getConfigData(page: Page): Promise<{ [key: string]: string }> {
27
+ if (configData) {
28
+ return configData;
29
+ }
30
+
31
+ configData = Object.create(null);
32
+
33
+ const el = await page.$('#jupyter-config-data');
34
+
35
+ if (!el) {
36
+ return {};
37
+ }
38
+
39
+ configData = JSON.parse((await el?.textContent()) ?? '{}');
40
+
41
+ for (const key in configData) {
42
+ // PageConfig expects strings
43
+ if (typeof configData[key] !== 'string') {
44
+ configData[key] = JSON.stringify(configData[key]);
45
+ }
46
+ }
47
+
48
+ return configData!;
49
+ }
50
+
51
+ /**
52
+ * Get a url-encoded item from `body.data` and decode it
53
+ * We should never have any encoded URLs anywhere else in code
54
+ * until we are building an actual request.
55
+ */
56
+ async function getBodyData(page: Page, key: string): Promise<string> {
57
+ const val = await page.evaluate(key => document.body.dataset[key], key);
58
+ if (typeof val === 'undefined') {
59
+ return '';
60
+ }
61
+ return decodeURIComponent(val);
62
+ }
63
+
64
+ /**
65
+ * Get the Jupyter server base URL stored in the index.html file
66
+ *
67
+ * @param page Playwright page model
68
+ * @returns Base URL
69
+ */
70
+ export async function getBaseUrl(page: Page): Promise<string> {
71
+ return URLExt.normalize((await getOption(page, 'baseUrl')) || '/');
72
+ }
73
+
74
+ /**
75
+ * Get the classes of an element
76
+ *
77
+ * @param element Element handle
78
+ * @returns Classes list
79
+ */
80
+ export async function getElementClassList(
81
+ element: ElementHandle
82
+ ): Promise<string[]> {
83
+ if (!element) {
84
+ return [];
85
+ }
86
+
87
+ const className = await element.getProperty('className');
88
+ if (className) {
89
+ const classNameList = await className.jsonValue();
90
+ if (typeof classNameList === 'string') {
91
+ return classNameList.split(' ');
92
+ }
93
+ }
94
+
95
+ return [];
96
+ }
97
+
98
+ /**
99
+ * List the content of a local directory
100
+ *
101
+ * @param dirPath Local directory path
102
+ * @param filePaths List to populate with the directory content
103
+ * @returns Content of the directory
104
+ */
105
+ export function getFilesInDirectory(
106
+ dirPath: string,
107
+ filePaths?: string[]
108
+ ): string[] {
109
+ const files = fs.readdirSync(dirPath);
110
+
111
+ filePaths = filePaths || [];
112
+
113
+ for (const file of files) {
114
+ if (file.startsWith('.')) {
115
+ continue;
116
+ }
117
+ if (fs.statSync(dirPath + '/' + file).isDirectory()) {
118
+ filePaths = getFilesInDirectory(dirPath + '/' + file, filePaths);
119
+ } else {
120
+ filePaths.push(path.join(dirPath, '/', file));
121
+ }
122
+ }
123
+
124
+ return filePaths;
125
+ }
126
+
127
+ /**
128
+ * Get the value of an option stored in the page config object
129
+ *
130
+ * @param page Playwright page model
131
+ * @param name Option name
132
+ * @returns Option value
133
+ */
134
+ export async function getOption(page: Page, name: string): Promise<string> {
135
+ return (await getConfigData(page))[name] ?? (await getBodyData(page, name));
136
+ }
137
+
138
+ /**
139
+ * Get the token stored in the page config object
140
+ *
141
+ * @param page Playwright page model
142
+ * @returns Token
143
+ */
144
+ export async function getToken(page: Page): Promise<string> {
145
+ return (
146
+ (await getOption(page, 'token')) ||
147
+ (await getBodyData(page, 'jupyterApiToken'))
148
+ );
149
+ }
150
+
151
+ /**
152
+ * Wait for a function to return true until timeout
153
+ *
154
+ * @param fn Condition
155
+ * @param timeout Time out
156
+ */
157
+ export async function waitForCondition(
158
+ fn: () => boolean | Promise<boolean>,
159
+ timeout?: number
160
+ ): Promise<void> {
161
+ return new Promise((resolve, reject) => {
162
+ let checkTimer: NodeJS.Timeout | null = null;
163
+ let timeoutTimer: NodeJS.Timeout | null = null;
164
+ const check = async () => {
165
+ checkTimer = null;
166
+ if (await Promise.resolve(fn())) {
167
+ if (timeoutTimer) {
168
+ clearTimeout(timeoutTimer);
169
+ }
170
+ resolve();
171
+ } else {
172
+ checkTimer = setTimeout(check, 200);
173
+ }
174
+ };
175
+
176
+ void check();
177
+
178
+ if (timeout) {
179
+ timeoutTimer = setTimeout(() => {
180
+ timeoutTimer = null;
181
+ if (checkTimer) {
182
+ clearTimeout(checkTimer);
183
+ }
184
+ reject(new Error('Timed out waiting for condition to be fulfilled.'));
185
+ }, timeout);
186
+ }
187
+ });
188
+ }
189
+
190
+ /**
191
+ * Wait for an element to emit 'transitionend' event.
192
+ *
193
+ * @param page Playwright page model object
194
+ * @param element Element or selector to watch
195
+ */
196
+ export async function waitForTransition(
197
+ page: Page,
198
+ element: ElementHandle<Element> | string
199
+ ): Promise<void> {
200
+ const el = typeof element === 'string' ? await page.$(element) : element;
201
+
202
+ if (el) {
203
+ return page.evaluate(el => {
204
+ return new Promise(resolve => {
205
+ const onEndHandler = () => {
206
+ el.removeEventListener('transitionend', onEndHandler);
207
+ resolve();
208
+ };
209
+ el.addEventListener('transitionend', onEndHandler);
210
+ });
211
+ }, el);
212
+ }
213
+
214
+ return Promise.reject();
215
+ }
216
+
217
+ // Selector builders
218
+
219
+ /**
220
+ * Get the selector to look for a specific class
221
+ *
222
+ * @param className Class name
223
+ * @returns Selector
224
+ */
225
+ export function xpContainsClass(className: string): string {
226
+ return `contains(concat(" ", normalize-space(@class), " "), " ${className} ")`;
227
+ }
228
+
229
+ /**
230
+ * Get the selector to look for a specific activity tab
231
+ *
232
+ * @param name Activity name
233
+ * @returns Selector
234
+ */
235
+ export function xpBuildActivityTabSelector(name: string): string {
236
+ return `//div[${xpContainsClass('jp-Activity')}]/ul/li[${xpContainsClass(
237
+ 'lm-TabBar-tab'
238
+ )} and ./div[text()="${name}" and ${xpContainsClass('lm-TabBar-tabLabel')}]]`;
239
+ }
240
+
241
+ /**
242
+ * Get the selector to look for a specific activity panel
243
+ *
244
+ * @param id Activity id
245
+ * @returns Selector
246
+ */
247
+ export function xpBuildActivityPanelSelector(id: string): string {
248
+ return `//div[@id='${id}' and ${xpContainsClass(
249
+ 'jp-Activity'
250
+ )} and ${xpContainsClass('lm-DockPanel-widget')}]`;
251
+ }
252
+
253
+ /**
254
+ * Get the selector to look for the currently active activity tab
255
+ *
256
+ * @returns Selector
257
+ */
258
+ export function xpBuildActiveActivityTabSelector(): string {
259
+ return `//div[${xpContainsClass('jp-Activity')}]/ul/li[${xpContainsClass(
260
+ 'lm-TabBar-tab'
261
+ )} and ${xpContainsClass('lm-mod-current')} and ./div[${xpContainsClass(
262
+ 'lm-TabBar-tabLabel'
263
+ )}]]`;
264
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+
6
+ // Type definitions for vega-statistics
7
+ // Project: vega-statistics
8
+ // Definitions by: Jupyter Development Team
9
+
10
+ declare module 'vega-statistics' {
11
+ export function quartiles(
12
+ array: number[],
13
+ accessor?: (t: any) => number
14
+ ): [number, number, number];
15
+ }
package/lib/global.d.ts DELETED
@@ -1,23 +0,0 @@
1
- import { JupyterFrontEnd } from '@jupyterlab/application';
2
- import { IGalataInpage } from './inpage/tokens';
3
- declare global {
4
- interface Window {
5
- /**
6
- * Access JupyterLab Application object
7
- *
8
- * @deprecated since v4
9
- * Please use window.jupyterapp to access the Jupyter Application
10
- */
11
- jupyterlab?: JupyterFrontEnd;
12
- /**
13
- * Access Jupyter Application object
14
- */
15
- jupyterapp: JupyterFrontEnd;
16
- /**
17
- * Access to Galata In-Page helpers
18
- *
19
- * Those helpers are injected when navigating to JupyterLab page
20
- */
21
- galataip: IGalataInpage;
22
- }
23
- }
package/lib/global.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"global.js","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":";AAAA,yDAAyD;AACzD,0CAA0C;AAC1C,sCAAsC;AACtC,2DAA2D"}
@@ -1,135 +0,0 @@
1
- import { IRouter, JupyterFrontEnd } from '@jupyterlab/application';
2
- import { IDocumentManager } from '@jupyterlab/docmanager';
3
- import { ISettingRegistry } from '@jupyterlab/settingregistry';
4
- /**
5
- * Cell execution callbacks interface
6
- */
7
- export interface INotebookRunCallback {
8
- /**
9
- * Callback before scrolling to the cell
10
- */
11
- onBeforeScroll?: () => Promise<void>;
12
- /**
13
- * Callback after scrolling to teh cell
14
- */
15
- onAfterScroll?: () => Promise<void>;
16
- /**
17
- * Callback after cell execution
18
- */
19
- onAfterCellRun?: (cellIndex: number) => Promise<void>;
20
- }
21
- /**
22
- * waitForSelector options
23
- */
24
- export interface IWaitForSelectorOptions {
25
- /**
26
- * Test for the element to be hidden.
27
- */
28
- hidden?: boolean;
29
- }
30
- export declare const PLUGIN_ID_ROUTER = "@jupyterlab/application-extension:router";
31
- export declare const PLUGIN_ID_DOC_MANAGER = "@jupyterlab/docmanager-extension:plugin";
32
- export declare const PLUGIN_ID_SETTINGS = "@jupyterlab/apputils-extension:settings";
33
- export interface IPluginNameToInterfaceMap {
34
- [PLUGIN_ID_ROUTER]: IRouter;
35
- [PLUGIN_ID_DOC_MANAGER]: IDocumentManager;
36
- [PLUGIN_ID_SETTINGS]: ISettingRegistry;
37
- }
38
- /**
39
- * Galata In-Page interface
40
- */
41
- export interface IGalataInpage {
42
- /**
43
- * Delete all cells of the active notebook
44
- */
45
- deleteNotebookCells(): Promise<void>;
46
- /**
47
- * Get the index of a toolbar item
48
- *
49
- * @param itemName Item name
50
- * @returns Index
51
- */
52
- getNotebookToolbarItemIndex(itemName: string): number;
53
- /**
54
- * Get an application plugin
55
- *
56
- * @param pluginId Plugin ID
57
- * @returns Application plugin
58
- */
59
- getPlugin<K extends keyof IPluginNameToInterfaceMap>(pluginId: K): Promise<IPluginNameToInterfaceMap[K] | undefined>;
60
- /**
61
- * Test if a cell is selected in the active notebook
62
- *
63
- * @param cellIndex Cell index
64
- * @returns Whether the cell is selected or not
65
- */
66
- isNotebookCellSelected(cellIndex: number): boolean;
67
- /**
68
- * Test if a element is visible or not
69
- *
70
- * @param el Element
71
- * @returns Test result
72
- */
73
- isElementVisible(el: HTMLElement): boolean;
74
- /**
75
- * Save the active notebook
76
- */
77
- saveActiveNotebook(): Promise<void>;
78
- /**
79
- * Set the application theme
80
- *
81
- * @param themeName Theme name
82
- */
83
- setTheme(themeName: string): Promise<void>;
84
- /**
85
- * Run the active notebook
86
- */
87
- runActiveNotebook(): Promise<void>;
88
- /**
89
- * Run the active notebook cell by cell
90
- * and execute the callback after each cell execution
91
- *
92
- * @param callback Callback
93
- */
94
- runActiveNotebookCellByCell(callback?: INotebookRunCallback): Promise<void>;
95
- /**
96
- * Wait for the route to be on path and close all documents
97
- *
98
- * @param path Path to monitor
99
- */
100
- waitForLaunch(path?: string): Promise<void>;
101
- /**
102
- * Wait for the route to be on path and close all documents
103
- *
104
- * @param path Path to monitor
105
- */
106
- waitForNotebookRun(): Promise<void>;
107
- /**
108
- * Wait for an element to be found from a CSS selector
109
- *
110
- * @param selector CSS selector
111
- * @param node Element
112
- * @param options Options
113
- * @returns Selected element
114
- */
115
- waitForSelector(selector: string, node?: Element, options?: IWaitForSelectorOptions): Promise<Node | null>;
116
- /**
117
- * Waits for the given `timeout` in milliseconds.
118
- *
119
- * @param timeout A timeout to wait for
120
- */
121
- waitForTimeout(duration: number): Promise<void>;
122
- /**
123
- * Wait for an element to be found from a XPath
124
- *
125
- * @param selector CSS selector
126
- * @param node Element
127
- * @param options Options
128
- * @returns Selected element
129
- */
130
- waitForXPath(selector: string, node?: Element, options?: IWaitForSelectorOptions): Promise<Node | null>;
131
- /**
132
- * Application object
133
- */
134
- readonly app: JupyterFrontEnd;
135
- }
@@ -1,9 +0,0 @@
1
- "use strict";
2
- // Copyright (c) Bloomberg Finance LP.
3
- // Distributed under the terms of the Modified BSD License.
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.PLUGIN_ID_SETTINGS = exports.PLUGIN_ID_DOC_MANAGER = exports.PLUGIN_ID_ROUTER = void 0;
6
- exports.PLUGIN_ID_ROUTER = '@jupyterlab/application-extension:router';
7
- exports.PLUGIN_ID_DOC_MANAGER = '@jupyterlab/docmanager-extension:plugin';
8
- exports.PLUGIN_ID_SETTINGS = '@jupyterlab/apputils-extension:settings';
9
- //# sourceMappingURL=tokens.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/inpage/tokens.ts"],"names":[],"mappings":";AAAA,sCAAsC;AACtC,2DAA2D;;;AAkC9C,QAAA,gBAAgB,GAAG,0CAA0C,CAAC;AAC9D,QAAA,qBAAqB,GAAG,yCAAyC,CAAC;AAClE,QAAA,kBAAkB,GAAG,yCAAyC,CAAC"}