1
1
"""Test save-as functionality"""
2
2
3
-
3
+ import sys
4
+ import time
4
5
import traceback
6
+ from functools import partial
7
+
8
+ import pytest
5
9
6
10
from .utils import EDITOR_PAGE , EndToEndTimeout
7
11
@@ -21,8 +25,9 @@ def set_notebook_name(nb, name):
21
25
nb .evaluate (JS , page = EDITOR_PAGE )
22
26
23
27
28
+ @pytest .mark .skipif (sys .platform == 'darwin' , reason = "fails randomly on osx" )
24
29
def test_save_as_nb (notebook_frontend ):
25
- print ('[Test] [test_save_readonly_as ]' )
30
+ print ('[Test] [test_save_as_notebook ]' )
26
31
notebook_frontend .wait_for_kernel_ready ()
27
32
notebook_frontend .wait_for_selector (".input" , page = EDITOR_PAGE )
28
33
@@ -50,17 +55,15 @@ def test_save_as_nb(notebook_frontend):
50
55
name_input_element = notebook_frontend .locate ('.modal-body .form-control' , page = EDITOR_PAGE )
51
56
name_input_element .focus ()
52
57
name_input_element .click ()
53
- notebook_name = 'new_notebook.ipynb'
54
58
55
- print ('[Test] Begin attempts to fill the save dialog input and save the notebook' )
56
59
fill_attempts = 0
57
60
58
- def attempt_form_fill_and_save ():
61
+ def attempt_form_fill_and_save (notebook_path ):
59
62
# Application behavior here is HIGHLY variable, we use this for repeated attempts
60
63
# ....................
61
64
# This may be a retry, check if the application state reflects a successful save operation
62
65
nonlocal fill_attempts
63
- if fill_attempts and get_notebook_name (notebook_frontend ) == "new_notebook.ipynb" :
66
+ if fill_attempts and get_notebook_name (notebook_frontend ) == notebook_path . split ( "/" )[ - 1 ] :
64
67
print ('[Test] Success from previous save attempt!' )
65
68
return True
66
69
fill_attempts += 1
@@ -92,6 +95,19 @@ def attempt_form_fill_and_save():
92
95
save_element .wait_for ('visible' )
93
96
save_element .focus ()
94
97
save_element .click ()
98
+ time .sleep (3 )
99
+ print ('[Test] Save button clicked' )
100
+
101
+ # If the notebook already exists from previous attempts or other tests,
102
+ # just overwrite it
103
+ if notebook_frontend .locate ('text=Overwrite' , page = EDITOR_PAGE ).is_visible ():
104
+ overwrite_element = notebook_frontend .locate ('text=Overwrite' , page = EDITOR_PAGE )
105
+ overwrite_element .focus ()
106
+ overwrite_element .click ()
107
+ time .sleep (3 )
108
+
109
+ save_element .wait_for ('detached' )
110
+ print ('[Test] Save element detached' )
95
111
96
112
# Application lag may cause the save dialog to linger,
97
113
# if it's visible wait for it to disappear before proceeding
@@ -112,11 +128,109 @@ def attempt_form_fill_and_save():
112
128
return True
113
129
114
130
# Retry until timeout (wait_for_condition retries upon func exception)
115
- notebook_frontend .wait_for_condition (attempt_form_fill_and_save , timeout = 900 , period = 1 )
131
+ notebook_frontend .wait_for_condition (
132
+ partial (attempt_form_fill_and_save , "new_notebook.ipynb" ),
133
+ timeout = 120 ,
134
+ period = 1 ,
135
+ )
116
136
117
137
print ('[Test] Check notebook name in URL' )
118
138
notebook_frontend .wait_for_condition (
119
- lambda : notebook_name in notebook_frontend .get_page_url (page = EDITOR_PAGE ),
139
+ lambda : get_notebook_name ( notebook_frontend ) in notebook_frontend .get_page_url (page = EDITOR_PAGE ),
120
140
timeout = 120 ,
121
141
period = 5
122
142
)
143
+
144
+ print ('[Test] Begin attempts to fill the save dialog input and save the notebook with a new directory' )
145
+ fill_attempts = 0
146
+
147
+ def attempt_form_fill_w_dir_and_save (notebook_path ):
148
+ # Application behavior here is HIGHLY variable, we use this for repeated attempts
149
+ # ....................
150
+ # This may be a retry, check if the application state reflects a successful save operation
151
+ nonlocal fill_attempts
152
+ if fill_attempts and get_notebook_name (notebook_frontend ) == notebook_path .split ("/" )[- 1 ]:
153
+ print ('[Test] Success from previous save attempt!' )
154
+ return True
155
+ fill_attempts += 1
156
+ print (f'[Test] Attempt form fill with directory and save #{ fill_attempts } ' )
157
+
158
+ # Make sure the save prompt is visible
159
+ if not name_input_element .is_visible ():
160
+ save_as (notebook_frontend )
161
+ name_input_element .wait_for ('visible' )
162
+
163
+ # Set the notebook name field in the save dialog
164
+ print ('[Test] Fill the input field' )
165
+ name_input_element .evaluate (f'(elem) => {{ elem.value = "{ notebook_path } "; return elem.value; }}' )
166
+ notebook_frontend .wait_for_condition (
167
+ lambda : name_input_element .evaluate (
168
+ f'(elem) => {{ elem.value = "{ notebook_path } "; return elem.value; }}' ) == notebook_path ,
169
+ timeout = 120 ,
170
+ period = .25
171
+ )
172
+ # Show the input field value
173
+ print ('[Test] Name input field contents:' )
174
+ field_value = name_input_element .evaluate ('(elem) => {{ return elem.value; }}' )
175
+ print ('[Test] ' + field_value )
176
+ if field_value != notebook_path :
177
+ return False
178
+
179
+ print ('[Test] Locate and click the save button' )
180
+ save_element = dialog_element .locate ('text=Save' )
181
+ save_element .wait_for ('visible' )
182
+ save_element .focus ()
183
+ save_element .click ()
184
+ time .sleep (3 )
185
+ print ('[Test] Save button clicked' )
186
+
187
+ # If the notebook path contains a directory, click the create button
188
+ if "/" in notebook_path :
189
+ print ('[Test] Locate and click the create button' )
190
+ create_element = dialog_element .locate ('text=Create' )
191
+ create_element .wait_for ('visible' )
192
+ create_element .focus ()
193
+ create_element .click ()
194
+ time .sleep (3 )
195
+
196
+ # If the notebook already exists from previous attempts or other tests,
197
+ # just overwrite it
198
+ if notebook_frontend .locate ('text=Overwrite' , page = EDITOR_PAGE ).is_visible ():
199
+ overwrite_element = notebook_frontend .locate ('text=Overwrite' , page = EDITOR_PAGE )
200
+ overwrite_element .focus ()
201
+ overwrite_element .click ()
202
+ time .sleep (3 )
203
+
204
+ # Application lag may cause the save dialog to linger,
205
+ # if it's visible wait for it to disappear before proceeding
206
+ if save_element .is_visible ():
207
+ print ('[Test] Save element still visible after save, wait for hidden' )
208
+ try :
209
+ save_element .expect_not_to_be_visible (timeout = 120 )
210
+ except EndToEndTimeout as err :
211
+ traceback .print_exc ()
212
+ print ('[Test] Save button failed to hide...' )
213
+
214
+ # Check if the save operation succeeded (by checking notebook name change)
215
+ notebook_frontend .wait_for_condition (
216
+ lambda : get_notebook_name (notebook_frontend ) == notebook_path .split ('/' )[- 1 ], timeout = 120 , period = 5
217
+ )
218
+ print (f'[Test] Notebook name: { get_notebook_name (notebook_frontend )} ' )
219
+ print ('[Test] Notebook name was changed!' )
220
+ return True
221
+
222
+ for notebook_path in ["new_notebook.ipynb" , "new_folder/another_new_notebook.ipynb" ]:
223
+ print (f'[Test] Begin attempts to fill the save dialog input with { notebook_path } and save the notebook' )
224
+ fill_attempts = 0
225
+ check_func = partial (attempt_form_fill_w_dir_and_save , notebook_path )
226
+ notebook_frontend .wait_for_condition (check_func , timeout = 900 , period = 1 )
227
+
228
+ print ('[Test] Check notebook name in URL' )
229
+ try :
230
+ notebook_frontend .wait_for_condition (
231
+ lambda : notebook_path .split ("/" )[- 1 ] in notebook_frontend .get_page_url (page = EDITOR_PAGE ),
232
+ timeout = 120 ,
233
+ period = 5
234
+ )
235
+ except :
236
+ print (notebook_frontend .get_page_url (page = EDITOR_PAGE ))
0 commit comments