Skip to content
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

Fix UI tests #81

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/developer/performance.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This widget will have a DOM structure like this:

<div class="jp-WindowedPanel-outer">
<div class="jp-WindowedPanel-inner">
<div class="jp-WindowedPanel-window">
<div class="jp-WindowedPanel-viewport">
<!-- Here will be the list of items in the viewport -->
</div>
</div>
Expand Down
5 changes: 5 additions & 0 deletions docs/source/extension/extension_migration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ See https://github.com/jupyterlab/team-compass/issues/143 for more context on th
The ``button`` elements in toolbars must be updated to ``jp-button``, from
`jupyter-ui-toolkit <https://github.com/jupyterlab-contrib/jupyter-ui-toolkit>`_.

CSS class name change in the ``WindowedList`` superclass of ``StaticNotebook``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The class ``.jp-WindowedPanel-window`` has been renamed to ``.jp-WindowedPanel-viewport``.
- The notebook scroll container is now ``.jp-WindowedPanel-outer`` rather than ``.jp-Notebook``
- Galata notebook helpers `getCell` and `getCellCount` were updated accordingly

JupyterLab 3.x to 4.x
---------------------
Expand Down
7 changes: 6 additions & 1 deletion examples/notebook/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
NotebookModelFactory,
NotebookPanel,
NotebookWidgetFactory,
StaticNotebook,
ToolbarItems
} from '@jupyterlab/notebook';
import {
Expand Down Expand Up @@ -205,7 +206,11 @@ function createApp(manager: ServiceManager.IManager): void {
rendermime,
contentFactory,
mimeTypeService,
toolbarFactory
toolbarFactory,
notebookConfig: {
...StaticNotebook.defaultNotebookConfig,
windowingMode: 'none'
}
});
docRegistry.addModelFactory(mFactory);
docRegistry.addWidgetFactory(wFactory);
Expand Down
41 changes: 23 additions & 18 deletions galata/src/helpers/notebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,21 +453,24 @@ export class NotebookHelper {
if (!notebook) {
return -1;
}
const scroller = (await notebook.$(
'.jp-WindowedPanel-outer'
)) as ElementHandle<HTMLElement>;

const scrollTop = await notebook.evaluate(node => node.scrollTop);
const scrollTop = await scroller.evaluate(node => node.scrollTop);

// Scroll to bottom
let previousScrollHeight = scrollTop;
let scrollHeight =
previousScrollHeight +
(await notebook.evaluate(node => node.clientHeight));
(await scroller.evaluate(node => node.clientHeight));
do {
await notebook.evaluate((node, scrollTarget) => {
await scroller.evaluate((node, scrollTarget) => {
node.scrollTo({ top: scrollTarget });
}, scrollHeight);
await this.page.waitForTimeout(50);
previousScrollHeight = scrollHeight;
scrollHeight = await notebook.evaluate(
scrollHeight = await scroller.evaluate(
node => node.scrollHeight - node.clientHeight
);
} while (scrollHeight > previousScrollHeight);
Expand All @@ -480,7 +483,7 @@ export class NotebookHelper {
) + 1;

// Scroll back to original position
await notebook.evaluate((node, scrollTarget) => {
await scroller.evaluate((node, scrollTarget) => {
node.scrollTo({ top: scrollTarget });
}, scrollTop);

Expand All @@ -498,6 +501,12 @@ export class NotebookHelper {
if (!notebook) {
return null;
}
const scroller = (await notebook.$(
'.jp-WindowedPanel-outer'
)) as ElementHandle<HTMLElement>;
const viewport = (await notebook.$(
'.jp-WindowedPanel-viewport'
)) as ElementHandle<HTMLElement>;

const allCells = await notebook.$$('div.jp-Cell');
const filters = await Promise.all(allCells.map(c => c.isVisible()));
Expand All @@ -519,10 +528,10 @@ export class NotebookHelper {
// Scroll up
let scrollTop =
(await firstCell.boundingBox())?.y ??
(await notebook.evaluate(node => node.scrollTop - node.clientHeight));
(await scroller.evaluate(node => node.scrollTop - node.clientHeight));

do {
await notebook.evaluate((node, scrollTarget) => {
await scroller.evaluate((node, scrollTarget) => {
node.scrollTo({ top: scrollTarget });
}, scrollTop);
await this.page.waitForTimeout(50);
Expand All @@ -538,20 +547,18 @@ export class NotebookHelper {
);
scrollTop =
(await cells[firstCell].boundingBox())?.y ??
(await notebook.evaluate(node => node.scrollTop - node.clientHeight));
(await scroller.evaluate(node => node.scrollTop - node.clientHeight));
} while (scrollTop > 0 && firstIndex > cellIndex);
} else if (cellIndex > lastIndex) {
const clientHeight = await notebook.evaluate(node => node.clientHeight);
const clientHeight = await scroller.evaluate(node => node.clientHeight);
// Scroll down
const viewport = await (
await notebook.$$('.jp-WindowedPanel-window')
)[0].boundingBox();
let scrollHeight = viewport!.y + viewport!.height;
const viewportBox = await viewport.boundingBox();
let scrollHeight = viewportBox!.y + viewportBox!.height;
let previousScrollHeight = 0;

do {
previousScrollHeight = scrollHeight;
await notebook.evaluate((node, scrollTarget) => {
await scroller.evaluate((node, scrollTarget) => {
node.scrollTo({ top: scrollTarget });
}, scrollHeight);
await this.page.waitForTimeout(50);
Expand All @@ -566,10 +573,8 @@ export class NotebookHelper {
10
);

const viewport = await (
await notebook.$$('.jp-WindowedPanel-window')
)[0].boundingBox();
scrollHeight = viewport!.y + viewport!.height;
const viewportBox = await viewport.boundingBox();
scrollHeight = viewportBox!.y + viewportBox!.height;
// Avoid jitter
scrollHeight = Math.max(
previousScrollHeight + clientHeight,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2030,6 +2030,12 @@
"Shift R"
]
},
{
"id": "notebook:toggle-virtual-scrollbar",
"label": "Virtual Scrollbar",
"caption": "Toggle virtual scrollbar (enabled with windowing mode: full)",
"shortcuts": []
},
{
"id": "notebook:trust",
"label": "Trust Notebook",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions galata/test/jupyterlab/notebook-scroll.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Distributed under the terms of the Modified BSD License.

import { expect, galata, test } from '@jupyterlab/galata';
import { ElementHandle } from '@playwright/test';
import * as path from 'path';

const fileName = 'scroll.ipynb';
Expand Down Expand Up @@ -75,7 +76,10 @@ test.describe('Notebook scroll on execution', () => {
const notebook = await page.notebook.getNotebookInPanel();
const thirdCell = await page.notebook.getCell(2);

const notebookBbox = await notebook.boundingBox();
const scroller = (await notebook.$(
'.jp-WindowedPanel-outer'
)) as ElementHandle<HTMLElement>;
const notebookBbox = await scroller.boundingBox();
const thirdCellBBox = await thirdCell.boundingBox();
await page.mouse.move(notebookBbox.x, notebookBbox.y);
const scrollOffset =
Expand Down Expand Up @@ -106,7 +110,10 @@ test.describe('Notebook scroll on execution', () => {
const notebook = await page.notebook.getNotebookInPanel();
const thirdCell = await page.notebook.getCell(2);

const notebookBbox = await notebook.boundingBox();
const scroller = (await notebook.$(
'.jp-WindowedPanel-outer'
)) as ElementHandle<HTMLElement>;
const notebookBbox = await scroller.boundingBox();
const thirdCellBBox = await thirdCell.boundingBox();
await page.mouse.move(notebookBbox.x, notebookBbox.y);
const scrollOffset =
Expand Down
2 changes: 1 addition & 1 deletion galata/test/jupyterlab/windowed-notebook.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async function getInnerHeight(panel: ElementHandle<Element>) {
async function getWindowHeight(panel: ElementHandle<Element>) {
return parseInt(
await panel.$eval(
'.jp-WindowedPanel-window',
'.jp-WindowedPanel-viewport',
node => (node as HTMLElement).style.minHeight
),
10
Expand Down
1 change: 0 additions & 1 deletion packages/lsp/src/adapters/tracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export class WidgetLSPAdapterTracker<
let newValue = args.newValue;

if (!newValue || !(newValue instanceof DocumentWidget)) {
console.log('No current widget');
return;
}

Expand Down
7 changes: 6 additions & 1 deletion packages/notebook-extension/schema/panel.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
{ "name": "cellType", "rank": 40 },
{ "name": "spacer", "type": "spacer", "rank": 100 },
{ "name": "kernelName", "rank": 1000 },
{ "name": "executionProgress", "rank": 1002 }
{ "name": "executionProgress", "rank": 1002 },
{
"name": "scrollbar",
"command": "notebook:toggle-virtual-scrollbar",
"rank": 1003
}
]
},
"jupyter.lab.transform": true,
Expand Down
53 changes: 49 additions & 4 deletions packages/notebook-extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ import {
pasteIcon,
refreshIcon,
runIcon,
stopIcon
stopIcon,
tableRowsIcon
} from '@jupyterlab/ui-components';
import { ArrayExt } from '@lumino/algorithm';
import { CommandRegistry } from '@lumino/commands';
Expand Down Expand Up @@ -319,6 +320,8 @@ namespace CommandIDs {
export const accessPreviousHistory = 'notebook:access-previous-history-entry';

export const accessNextHistory = 'notebook:access-next-history-entry';

export const virtualScrollbar = 'notebook:toggle-virtual-scrollbar';
}

/**
Expand Down Expand Up @@ -1629,6 +1632,7 @@ function activateNotebookHandler(
updateConfig(settings);
settings.changed.connect(() => {
updateConfig(settings);
commands.notifyCommandChanged(CommandIDs.virtualScrollbar);
});

const updateSessionSettings = (
Expand Down Expand Up @@ -1723,6 +1727,14 @@ function activateNotebookHandler(
.catch(console.error);
}
});
addCommands(
app,
tracker,
translator,
sessionDialogs,
settings,
isEnabled
);
})
.catch((reason: Error) => {
console.warn(reason.message);
Expand All @@ -1732,6 +1744,7 @@ function activateNotebookHandler(
kernelShutdown: factory.shutdownOnClose,
autoStartDefault: factory.autoStartDefault
});
addCommands(app, tracker, translator, sessionDialogs, null, isEnabled);
});

if (formRegistry) {
Expand Down Expand Up @@ -1772,8 +1785,6 @@ function activateNotebookHandler(
});
registry.addModelFactory(modelFactory);

addCommands(app, tracker, translator, sessionDialogs, isEnabled);

if (palette) {
populatePalette(palette, translator);
}
Expand Down Expand Up @@ -1806,6 +1817,14 @@ function activateNotebookHandler(
tracker.forEach(widget => {
widget.setConfig(options);
});
if (options.notebookConfig.windowingMode !== 'full') {
// Disable all virtual scrollbars if any was enabled
tracker.forEach(widget => {
if (widget.content.scrollbar) {
widget.content.scrollbar = false;
}
});
}
}

/**
Expand Down Expand Up @@ -2119,6 +2138,7 @@ function addCommands(
tracker: NotebookTracker,
translator: ITranslator,
sessionDialogs: ISessionContextDialogs,
settings: ISettingRegistry.ISettings | null,
isEnabled: () => boolean
): void {
const trans = translator.load('jupyterlab');
Expand Down Expand Up @@ -3398,7 +3418,6 @@ function addCommands(
}
}
});

commands.addCommand(CommandIDs.tocRunCells, {
label: trans.__('Select and Run Cell(s) for this Heading'),
execute: args => {
Expand Down Expand Up @@ -3458,6 +3477,32 @@ function addCommands(
}
}
});
commands.addCommand(CommandIDs.virtualScrollbar, {
label: trans.__('Virtual Scrollbar'),
caption: trans.__(
'Toggle virtual scrollbar (enabled with windowing mode: full)'
),
execute: args => {
const current = getCurrent(tracker, shell, args);

if (current) {
current.content.scrollbar = !current.content.scrollbar;
}
},
icon: args => (args.toolbar ? tableRowsIcon : undefined),
isEnabled: args => {
const enabled =
(args.toolbar ? true : isEnabled()) &&
(settings?.composite.windowingMode === 'full' ?? false);
return enabled;
},
isVisible: args => {
const visible =
(args.toolbar ? true : isEnabled()) &&
(settings?.composite.windowingMode === 'full' ?? false);
return visible;
}
});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/notebook/src/searchprovider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ export class NotebookSearchProvider extends SearchProvider<NotebookPanel> {
// change, and if selection is getting extended, we do not want to clear
// highlights just to re-apply them shortly after, which has side effects
// impacting the functionality and performance.
this._delayedActiveCellChangeHandler = setTimeout(() => {
this._delayedActiveCellChangeHandler = window.setTimeout(() => {
this.delayedActiveCellChangeHandlerReady =
this._handleHighlightsAfterActiveCellChange();
}, 0);
Expand Down
Loading
Loading