@@ -3,12 +3,20 @@ import path from 'path';
33import type { JupyterLab } from '@jupyterlab/application' ;
44import type { JSONObject } from '@lumino/coreutils' ;
55
6+ import { SharingService } from '../../src/sharing-service' ;
7+
68declare global {
79 interface Window {
810 jupyterapp : JupyterLab ;
911 }
1012}
1113
14+ declare global {
15+ interface Window {
16+ sharingService ?: SharingService ;
17+ }
18+ }
19+
1220async function runCommand ( page : Page , command : string , args : JSONObject = { } ) {
1321 await page . evaluate (
1422 async ( { command, args } ) => {
@@ -18,63 +26,30 @@ async function runCommand(page: Page, command: string, args: JSONObject = {}) {
1826 ) ;
1927}
2028
21- const TEST_NOTEBOOK = {
22- cells : [
23- {
24- cell_type : 'code' ,
25- execution_count : null ,
26- id : '55eb9a2d-401d-4abd-b0eb-373ded5b408d' ,
27- outputs : [ ] ,
28- metadata : { } ,
29- source : [ `# This is a test notebook` ]
30- }
31- ] ,
32- metadata : {
33- kernelspec : {
34- display_name : 'Python 3 (ipykernel)' ,
35- language : 'python' ,
36- name : 'python3'
37- } ,
38- language_info : {
39- codemirror_mode : {
40- name : 'ipython' ,
41- version : 3
42- } ,
43- file_extension : '.py' ,
44- mimetype : 'text/x-python' ,
45- name : 'python' ,
46- nbconvert_exporter : 'python' ,
47- pygments_lexer : 'ipython3'
48- }
49- } ,
50- nbformat : 4 ,
51- nbformat_minor : 5
52- } ;
53-
54- async function mockGetSharedNotebook ( page : Page , notebookId : string ) {
55- await page . route ( '**/api/v1/notebooks/*' , async route => {
56- const json = {
57- id : notebookId ,
58- domain_id : 'domain' ,
59- readable_id : null ,
60- content : TEST_NOTEBOOK
61- } ;
62- await route . fulfill ( { json } ) ;
29+ async function dismissKernelSelectDialog ( page : Page ) {
30+ const kernelDialogHeader = page . locator ( '.jp-Dialog .jp-Dialog-header' , {
31+ hasText : 'Select Kernel'
6332 } ) ;
33+
34+ if ( ( await kernelDialogHeader . count ( ) ) === 0 ) {
35+ return ;
36+ }
37+
38+ const selectButtonLabel = kernelDialogHeader . locator (
39+ 'xpath=../../..//div[@aria-label="Select Kernel"]'
40+ ) ;
41+
42+ if ( await selectButtonLabel . count ( ) ) {
43+ await selectButtonLabel . first ( ) . click ( ) ;
44+ }
6445}
6546
66- async function mockShareNotebookResponse ( page : Page , notebookId : string ) {
67- await page . route ( '**/api/v1/notebooks' , async route => {
68- const json = {
69- message : 'Shared!' ,
70- notebook : { id : notebookId , readable_id : null }
71- } ;
72- await route . fulfill ( { json } ) ;
73- } ) ;
47+ async function getSharedNotebookID ( page : Page ) {
48+ return new URL ( page . url ( ) ) . searchParams . get ( 'notebook' ) ;
7449}
7550
7651test . beforeEach ( async ( { page } ) => {
77- await page . goto ( 'lab/index.html' ) ;
52+ await page . goto ( 'lab/index.html?kernel=python ' ) ;
7853 await page . waitForSelector ( '.jp-LabShell' ) ;
7954
8055 // Clear token before each test
@@ -95,11 +70,13 @@ test.describe('General', () => {
9570 } ) ;
9671
9772 test ( 'Dialog windows should shade the notebook area only' , async ( { page } ) => {
73+ await dismissKernelSelectDialog ( page ) ;
9874 const firstCell = page . locator ( '.jp-Cell' ) ;
9975 await firstCell
10076 . getByRole ( 'textbox' )
10177 . fill ( 'The shaded area should cover the notebook content, but not the toolbar.' ) ;
10278 const promise = runCommand ( page , 'notebook:restart-kernel' ) ;
79+ await dismissKernelSelectDialog ( page ) ;
10380 const dialog = page . locator ( '.jp-Dialog' ) ;
10481
10582 expect (
@@ -115,19 +92,13 @@ test.describe('General', () => {
11592 } ) ;
11693
11794 test ( 'Should load a view-only notebook' , async ( { page } ) => {
118- const notebookId = 'e3b0c442-98fc-1fc2-9c9f-8b6d6ed08a1d' ;
119-
120- await page . route ( '**/api/v1/notebooks/*' , async route => {
121- const json = {
122- id : notebookId ,
123- domain_id : 'domain' ,
124- readable_id : null ,
125- content : TEST_NOTEBOOK
126- } ;
127- await route . fulfill ( { json } ) ;
128- } ) ;
95+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
12996
130- await page . goto ( `lab/index.html?notebook=${ notebookId } ` ) ;
97+ const notebookId = await getSharedNotebookID ( page ) ;
98+ expect ( notebookId ) . not . toBeNull ( ) ;
99+
100+ await page . goto ( `lab/index.html?notebook=${ notebookId } &kernel=python` ) ;
101+ dismissKernelSelectDialog ( page ) ;
131102
132103 expect (
133104 await page . locator ( '.jp-NotebookPanel' ) . screenshot ( {
@@ -139,33 +110,31 @@ test.describe('General', () => {
139110
140111 test ( 'Should open files page' , async ( { page } ) => {
141112 await page . locator ( '.jp-SideBar' ) . getByTitle ( 'Files' ) . click ( ) ;
113+ await dismissKernelSelectDialog ( page ) ;
142114 expect ( await page . locator ( '#je-files' ) . screenshot ( ) ) . toMatchSnapshot ( 'files.png' ) ;
143115 } ) ;
144116} ) ;
145117
146118test . describe ( 'Sharing' , ( ) => {
147119 test ( 'Should open share dialog in interactive notebook' , async ( { page } ) => {
148- await mockShareNotebookResponse ( page , 'e3b0c442-98fc-1fc2-9c9f-8b6d6ed08a1d' ) ;
149- const shareButton = page . locator ( '.jp-ToolbarButton' ) . getByTitle ( 'Share this notebook' ) ;
150- await shareButton . click ( ) ;
120+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
151121 const dialog = page . locator ( '.jp-Dialog-content' ) ;
152122 expect ( await dialog . screenshot ( ) ) . toMatchSnapshot ( 'share-dialog.png' ) ;
153123 } ) ;
154124
155125 test ( 'Should open share dialog in view-only mode' , async ( { page } ) => {
156126 // Load view-only (shared) notebook
157- const notebookId = 'e3b0c442-98fc-1fc2-9c9f-8b6d6ed08a1d' ;
158- await mockGetSharedNotebook ( page , notebookId ) ;
159- await page . goto ( `lab/index.html?notebook= ${ notebookId } ` ) ;
127+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
128+ const notebookId = await getSharedNotebookID ( page ) ;
129+ expect ( notebookId ) . not . toBeNull ( ) ;
160130
161- // Re-Share it as a new notebook
162- const newNotebookId = '104931f8-fd96-489e-8520-c1793cbba6ce' ;
163- await mockShareNotebookResponse ( page , newNotebookId ) ;
131+ // Re-share it as a new notebook
132+ await page . goto ( `lab/index.html?notebook= ${ notebookId } &kernel=python` ) ;
133+ dismissKernelSelectDialog ( page ) ;
164134
165- const shareButton = page . locator ( '.jp-ToolbarButton' ) . getByTitle ( 'Share this notebook' ) ;
166135 const dialog = page . locator ( '.jp-Dialog-content' ) ;
167136 await expect ( dialog ) . toHaveCount ( 0 ) ;
168- await shareButton . click ( ) ;
137+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
169138 await expect ( dialog ) . toHaveCount ( 1 ) ;
170139 } ) ;
171140} ) ;
@@ -180,7 +149,10 @@ test.describe('Download', () => {
180149 } ) ;
181150
182151 test ( 'Should download a notebook as IPyNB and PDF' , async ( { page, context } ) => {
183- await mockShareNotebookResponse ( page , 'test-download-regular-notebook' ) ;
152+ dismissKernelSelectDialog ( page ) ;
153+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
154+ await getSharedNotebookID ( page ) ;
155+ dismissKernelSelectDialog ( page ) ;
184156
185157 const ipynbDownload = page . waitForEvent ( 'download' ) ;
186158 await runCommand ( page , 'jupytereverywhere:download-notebook' ) ;
@@ -194,32 +166,32 @@ test.describe('Download', () => {
194166 } ) ;
195167
196168 test ( 'Should download view-only notebook as IPyNB and PDF' , async ( { page } ) => {
197- const notebookId = 'e3b0c442-98fc-1fc2-9c9f-8b6d6ed08a1d' ;
198- await mockGetSharedNotebook ( page , notebookId ) ;
199- await mockShareNotebookResponse ( page , 'test-download-viewonly-notebook' ) ;
169+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
170+ const notebookId = await getSharedNotebookID ( page ) ;
171+ expect ( notebookId ) . not . toBeNull ( ) ;
200172
201- await page . goto ( `lab/index.html?notebook=${ notebookId } ` ) ;
173+ await page . goto ( `lab/index.html?notebook=${ notebookId } &kernel=python` ) ;
174+ dismissKernelSelectDialog ( page ) ;
202175
203176 // Wait until view-only notebook loads, and assert it is a view-only notebook.
204177 await page . locator ( '.jp-NotebookPanel' ) . waitFor ( ) ;
205178 await expect ( page . locator ( '.je-ViewOnlyHeader' ) ) . toBeVisible ( ) ;
206179
207180 const ipynbDownload = page . waitForEvent ( 'download' ) ;
208- await runCommand ( page , 'jupytereverywhere:download-pdf ' ) ;
181+ await runCommand ( page , 'jupytereverywhere:download-notebook ' ) ;
209182 const ipynbPath = await ( await ipynbDownload ) . path ( ) ;
210183 expect ( ipynbPath ) . not . toBeNull ( ) ;
211184
212185 const pdfDownload = page . waitForEvent ( 'download' ) ;
213186 await runCommand ( page , 'jupytereverywhere:download-pdf' ) ;
214-
215187 const pdfPath = await ( await pdfDownload ) . path ( ) ;
216188 expect ( pdfPath ) . not . toBeNull ( ) ;
217189 } ) ;
218190} ) ;
219191
220192test . describe ( 'Files' , ( ) => {
221193 test ( 'Should upload two files and display their thumbnails' , async ( { page } ) => {
222- await page . goto ( 'lab/index.html' ) ;
194+ await page . goto ( 'lab/index.html?kernel=python ' ) ;
223195 await page . waitForSelector ( '.jp-LabShell' ) ;
224196
225197 await page . locator ( '.jp-SideBar' ) . getByTitle ( 'Files' ) . click ( ) ;
@@ -250,15 +222,15 @@ test.describe('Files', () => {
250222} ) ;
251223
252224test ( 'Should remove View Only banner when the Create Copy button is clicked' , async ( { page } ) => {
253- const notebookId = 'e3b0c442-98fc-1fc2-9c9f-8b6d6ed08a1d' ;
254- await mockGetSharedNotebook ( page , notebookId ) ;
225+ await runCommand ( page , 'jupytereverywhere:share-notebook' ) ;
226+ const notebookId = await getSharedNotebookID ( page ) ;
227+ expect ( notebookId ) . not . toBeNull ( ) ;
255228
256229 // Open view-only notebook
257- await page . goto ( `lab/index.html?notebook=${ notebookId } ` ) ;
230+ await page . goto ( `lab/index.html?notebook=${ notebookId } &kernel=python ` ) ;
258231 await expect ( page . locator ( '.je-ViewOnlyHeader' ) ) . toBeVisible ( ) ;
259232
260- const createCopyButton = page . locator ( '.jp-ToolbarButtonComponent.je-CreateCopyButton' ) ;
261- await createCopyButton . click ( ) ;
233+ await runCommand ( page , 'jupytereverywhere:create-copy-notebook' ) ;
262234 await expect ( page . locator ( '.je-ViewOnlyHeader' ) ) . toBeHidden ( {
263235 timeout : 10000
264236 } ) ;
0 commit comments