1
1
import logging
2
2
import os
3
+ import re
3
4
import subprocess
4
5
import time
6
+ from pathlib import Path
5
7
6
8
import pytest
7
9
from selenium .webdriver .support .wait import WebDriverWait
@@ -314,8 +316,6 @@ def test_studio_default_domain_multiple_users(request):
314
316
assert "test-data-science" in user_profile_name
315
317
316
318
317
- @pytest .mark .skipif (os .getenv ('PYTEST_IGNORE_SKIPS' , "false" ) == "false" ,
318
- reason = "Not yet stable" )
319
319
def test_studio_notebook_in_firefox (request ):
320
320
ide = SSHIDE (request .config .getini ('sagemaker_studio_domain' ), 'test-data-science' )
321
321
@@ -337,44 +337,64 @@ def test_studio_notebook_in_firefox(request):
337
337
assert "JupyterLab" in browser .title
338
338
339
339
logging .info ("Waiting for SageMaker Studio to launch" )
340
- WebDriverWait (browser , 300 ).until (
341
- EC .presence_of_element_located ((By .XPATH , "//div[@id='jp-MainLogo ']" ))
340
+ WebDriverWait (browser , 600 ).until (
341
+ EC .presence_of_element_located ((By .XPATH , "//div[@id='space-menu ']" ))
342
342
)
343
- time .sleep (15 ) # wait until obscurity of the menu item is gone and UI is fully loaded
343
+ kernel_menu_item = browser .find_element (By .XPATH , "//div[@id='space-menu']" )
344
+ logging .info (f"Found SageMaker Studio space menu item: { kernel_menu_item .text } " )
345
+ assert kernel_menu_item .text == 'test-data-science / Personal Studio'
346
+
347
+ time .sleep (10 ) # wait until obscurity of the menu items is gone and UI is fully loaded
348
+
349
+ dist_file_name_pattern = 'sagemaker_ssh_helper-.*-py3-none-any.whl'
350
+ dist_file_name = [f for f in os .listdir ('../dist' ) if re .match (dist_file_name_pattern , f )][0 ]
351
+ logging .info (f"Found dist file: { dist_file_name } " )
344
352
345
- # TODO: ide.upload_ssh("../SageMaker_SSH_IDE.ipynb", "/root/SageMaker_SSH_IDE-DS2-CPU.ipynb")
346
- # TODO: ide.upload_UI("../SageMaker_SSH_IDE.ipynb", "/SageMaker_SSH_IDE-DS2-CPU.ipynb")
347
- # TODO: ide.upload_UI("../", "/sagemaker-ssh-helper", exclude=["*"], include=["setup.py", "sagemaker_ssh_helper/"])
348
353
# TODO: File -> Reload notebook from Disk
349
354
# TODO: ide.add_new_cell([
350
- # "%%sh"
351
- # "pip3 install -U ./sagemaker-ssh-helper/ "
355
+ # f "%%sh"
356
+ # f "pip3 install -U ./{dist_file_name} "
352
357
# ])
353
358
354
- kernel_menu_xpath = "//div[@class='lm-MenuBar-itemLabel p-MenuBar-itemLabel' " \
355
- "and text()='Kernel']"
356
- kernel_menu_item = browser .find_element (By .XPATH , kernel_menu_xpath )
357
- logging .info (f"Found SageMaker Studio kernel menu item: { kernel_menu_item } " )
359
+ upload_file (browser , os .path .abspath ("../SageMaker_SSH_IDE.ipynb" ))
360
+ logging .info ("IDE notebook uploaded" )
361
+ upload_file (browser , os .path .abspath (Path ("../dist/" , dist_file_name )))
362
+ logging .info ("Dist file uploaded" )
363
+
364
+ kernel_menu_item = browser .find_element (
365
+ By .XPATH ,
366
+ "//div[@class='lm-MenuBar-itemLabel p-MenuBar-itemLabel' "
367
+ "and text()='Kernel']"
368
+ )
369
+ logging .info (f"Found SageMaker Studio kernel menu item: { kernel_menu_item .text } " )
358
370
kernel_menu_item .click ()
359
371
360
372
logging .info ("Restarting kernel and running all cells" )
361
- restart_menu_xpath = "//div[@class='lm-Menu-itemLabel p-Menu-itemLabel' " \
362
- "and text()='Restart Kernel and Run All Cells…']"
363
- restart_menu_item = browser .find_element (By .XPATH , restart_menu_xpath )
364
- logging .info (f"Found SageMaker Studio restart kernel menu item: { restart_menu_item } " )
373
+ restart_menu_item = browser .find_element (
374
+ By .XPATH ,
375
+ "//div[@class='lm-Menu-itemLabel p-Menu-itemLabel' "
376
+ "and text()='Restart Kernel and Run All Cells…']" )
377
+ logging .info (f"Found SageMaker Studio restart kernel menu item: { restart_menu_item .text } " )
365
378
restart_menu_item .click ()
366
379
367
- # TODO: check if kernel has been already started, also check that it's a correct kernel and instance type
368
- # <button type="button" class="bp3-button bp3-minimal jp-Toolbar-kernelName jp-ToolbarButtonComponent minimal jp-Button" aria-disabled="false" title="Switch kernel"><span class="bp3-button-text"><span class="jp-ToolbarButtonComponent-label">No Kernel</span></span></button>
369
- # <button type="button" class="bp3-button bp3-minimal jp-Toolbar-kernelName jp-ToolbarButtonComponent minimal jp-Button" aria-disabled="false" title=""><span class="bp3-button-text"><span class="jp-ToolbarButtonComponent-label" style="display: none;">Python 3 (Data Science 2.0)</span></span><span class="css-1jyspix newButtonTarget"><span class="css-1vcsdgo">Data Science 2.0</span><span class="css-pyakce">|</span><span>Python 3</span><span class="css-pyakce">|</span><span>2 vCPU + 4 GiB</span></span></button>
380
+ logging .info ("Checking the kernel name" )
381
+ kernel_item = browser .find_element (
382
+ By .XPATH ,
383
+ "//button[@class='bp3-button bp3-minimal jp-Toolbar-kernelName "
384
+ "jp-ToolbarButtonComponent minimal jp-Button']"
385
+ )
386
+ logging .info (f"Found Kernel name: { kernel_item .text } " )
387
+ assert kernel_item .text == "Data Science 2.0\n |\n Python 3\n |\n 2 vCPU + 8 GiB"
370
388
371
389
# TODO: check banner if kernel is still starting, wait until banner disappears, then click restart
372
390
# <div class="css-a7sx0c-bannerContainer sagemaker-starting-banner" id="sagemaker-notebook-banner"><div class="css-1qyc1pu-kernelStartingBannerContainer"><div><div class="css-6wrpfe-bannerSpinDiv"></div></div><div><p class="css-g9mx5z-bannerPromptSpanTitle">Starting notebook kernel...</p></div></div></div>
373
391
374
- restart_button_xpath = "//div[@class='jp-Dialog-buttonLabel' " \
375
- "and text()='Restart']"
376
- restart_button = browser .find_element (By .XPATH , restart_button_xpath )
377
- logging .info (f"Found SageMaker Studio restart button: { restart_button } " )
392
+ restart_button = browser .find_element (
393
+ By .XPATH ,
394
+ "//div[@class='jp-Dialog-buttonLabel' "
395
+ "and text()='Restart']"
396
+ )
397
+ logging .info (f"Found SageMaker Studio restart button: { restart_button .text } " )
378
398
restart_button .click ()
379
399
380
400
time .sleep (120 ) # Give time to restart
@@ -404,3 +424,28 @@ def test_studio_notebook_in_firefox(request):
404
424
405
425
logging .info ("Closing Firefox" )
406
426
browser .close ()
427
+
428
+
429
+ def upload_file (browser , file_abs_path ):
430
+ file_drop_area = browser .find_element (
431
+ By .XPATH ,
432
+ "//ul[@class='jp-DirListing-content']"
433
+ )
434
+ logging .info (f"Found file browser to drop the file to: { file_drop_area .text } " )
435
+ time .sleep (2 )
436
+ file_input = browser .execute_script (Path ('js/drop_studio_file.js' ).read_text (), file_drop_area , 0 , 0 )
437
+ logging .info (f"Created a file upload item: { file_input } " )
438
+ file_input .send_keys (file_abs_path )
439
+ time .sleep (5 ) # Give time to overwrite dialog to apper
440
+ confirmOverride (browser )
441
+
442
+
443
+ def confirmOverride (browser ):
444
+ overwrite_button = browser .find_elements (
445
+ By .XPATH ,
446
+ "//div[@class='jp-Dialog-buttonLabel' "
447
+ "and text()='Overwrite']"
448
+ )
449
+ if len (overwrite_button ) > 0 :
450
+ logging .info (f"Found overwrite dialog button: { overwrite_button [0 ].text } " )
451
+ overwrite_button [0 ].click ()
0 commit comments