Skip to content

Commit ef753f8

Browse files
Add functional test for the sharing service
1 parent bce631a commit ef753f8

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { test, expect, Page } from '@playwright/test';
2+
import type { JupyterLab } from '@jupyterlab/application';
3+
import type { JSONObject } from '@lumino/coreutils';
4+
5+
declare global {
6+
interface Window {
7+
jupyterapp: JupyterLab;
8+
}
9+
}
10+
11+
async function runCommand(page: Page, command: string, args: JSONObject = {}) {
12+
await page.evaluate(
13+
async ({ command, args }) => {
14+
await window.jupyterapp.commands.execute(command, args);
15+
},
16+
{ command, args }
17+
);
18+
}
19+
20+
const TEST_NOTEBOOK = {
21+
cells: [
22+
{
23+
cell_type: 'code',
24+
execution_count: null,
25+
id: 'test-cell-1',
26+
outputs: [],
27+
metadata: {},
28+
source: ['print("Hello from CKHub shared notebook!")']
29+
},
30+
{
31+
cell_type: 'markdown',
32+
id: 'test-cell-2',
33+
metadata: {},
34+
source: ['# Test Markdown Cell\n\nThis is a test notebook for sharing.']
35+
}
36+
],
37+
metadata: {
38+
kernelspec: {
39+
display_name: 'Python 3 (ipykernel)',
40+
language: 'python',
41+
name: 'python3'
42+
},
43+
language_info: {
44+
name: 'python',
45+
version: '3.8.0'
46+
}
47+
},
48+
nbformat: 4,
49+
nbformat_minor: 5
50+
};
51+
52+
async function createTestNotebook(page: Page): Promise<void> {
53+
await page.evaluate(notebookContent => {
54+
const { serviceManager } = window.jupyterapp;
55+
return serviceManager.contents.save('test-notebook.ipynb', {
56+
type: 'notebook',
57+
format: 'json',
58+
content: notebookContent
59+
});
60+
}, TEST_NOTEBOOK);
61+
}
62+
63+
async function openTestNotebook(page: Page): Promise<void> {
64+
await runCommand(page, 'docmanager:open', { path: 'test-notebook.ipynb' });
65+
}
66+
67+
async function extractShareUrlFromDialog(page: Page): Promise<string> {
68+
const shareUrlElement = await page.waitForSelector('.je-share-link', { timeout: 10000 });
69+
const shareUrl = await shareUrlElement.textContent();
70+
71+
if (!shareUrl) {
72+
throw new Error('Share URL not found in dialog');
73+
}
74+
75+
return shareUrl.trim();
76+
}
77+
78+
async function getCellContent(page: Page, cellIndex: number = 0): Promise<string> {
79+
return await page.evaluate(index => {
80+
const cells = document.querySelectorAll('.jp-Cell');
81+
const cell = cells[index];
82+
if (!cell) return '';
83+
84+
const content = cell.querySelector('.cm-content');
85+
return content?.textContent || '';
86+
}, cellIndex);
87+
}
88+
89+
test.beforeEach(async ({ page }) => {
90+
await page.goto('lab/index.html');
91+
await page.waitForSelector('.jp-LabShell');
92+
});
93+
94+
test.describe('A functional test for the sharing service', () => {
95+
test('Perform round-trip with sharing service', async ({ page, context }) => {
96+
await createTestNotebook(page);
97+
await openTestNotebook(page);
98+
await runCommand(page, 'jupytereverywhere:share-notebook');
99+
100+
const shareUrl = await extractShareUrlFromDialog(page);
101+
102+
const sharedPage = await context.newPage();
103+
await sharedPage.goto(shareUrl);
104+
await sharedPage.waitForSelector('.jp-LabShell');
105+
106+
await runCommand(sharedPage, 'jupytereverywhere:create-copy-notebook');
107+
108+
// Wait for view-only header to disappear
109+
await expect(sharedPage.locator('.je-ViewOnlyHeader')).toBeHidden({ timeout: 10000 });
110+
111+
await sharedPage.close();
112+
});
113+
});

0 commit comments

Comments
 (0)