Skip to content

Commit 4830b98

Browse files
authored
Merge pull request #406 from bollwyvl/fix-gh-403-spaces
investigate escaping jumping to definition (and other features) with spaces
2 parents a952949 + c82eb1b commit 4830b98

File tree

29 files changed

+229
-110
lines changed

29 files changed

+229
-110
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
## CHANGELOG
22

3+
### `@krassowski/jupyterlab-lsp 2.0.9` (???)
4+
5+
- bug fixes
6+
7+
- handles characters that need escaping (spaces, non-ASCII characters) more
8+
robustly in files and folder names ([#403])
9+
10+
[#403]: https://github.com/krassowski/jupyterlab-lsp/issues/403
11+
12+
### `@krassowski/jupyterlab_go_to_definition 2.0.0` (???)
13+
14+
- features
15+
16+
- breaking change: renames `uri` to `contents_path` to help avoid programmer issues
17+
with characters requiring URI encoding ([#406])
18+
19+
[#406]: https://github.com/krassowski/jupyterlab-lsp/pull/406
20+
321
### `@krassowski/jupyterlab-lsp 2.0.8` (2020-10-25)
422

523
- bug fixes

atest/00_Smoke.robot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
*** Settings ***
2-
Suite Setup Set Screenshot Directory ${OUTPUT DIR}${/}screenshots${/}smoke
2+
Suite Setup Set Screenshot Directory ${SCREENSHOTS DIR}${/}smoke
33
Resource Keywords.robot
44

55
*** Test Cases ***

atest/01_Editor.robot

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*** Settings ***
22
Suite Setup Setup Suite For Screenshots editor
3-
Force Tags ui:editor
3+
Force Tags ui:editor aspect:ls:features
44
Resource Keywords.robot
55
Resource Variables.robot
66

@@ -90,29 +90,6 @@ Editor Should Show Diagnostics
9090
Should Be True ${count} >= 1
9191
Close Diagnostics Panel
9292

93-
Editor Should Jump To Definition
94-
[Arguments] ${symbol}
95-
Set Tags feature:jump-to-definition
96-
${sel} = Set Variable If "${symbol}".startswith(("xpath", "css")) ${symbol} xpath:(//span[@role="presentation"][contains(., "${symbol}")])[last()]
97-
Open Context Menu Over ${sel}
98-
${cursor} = Measure Cursor Position
99-
Capture Page Screenshot 02-jump-to-definition-0.png
100-
Mouse Over ${MENU JUMP}
101-
Capture Page Screenshot 02-jump-to-definition-1.png
102-
Click Element ${MENU JUMP}
103-
Wait Until Keyword Succeeds 10 x 1 s Cursor Should Jump ${cursor}
104-
Capture Page Screenshot 02-jump-to-definition-2.png
105-
106-
Cursor Should Jump
107-
[Arguments] ${original}
108-
${current} = Measure Cursor Position
109-
Should Not Be Equal ${original} ${current}
110-
111-
Measure Cursor Position
112-
Wait Until Page Contains Element ${CM CURSORS}
113-
${position} = Wait Until Keyword Succeeds 20 x 0.05s Get Vertical Position ${CM CURSOR}
114-
[Return] ${position}
115-
11693
Editor Content Changed
11794
[Arguments] ${old_content}
11895
${new_content} Get Editor Content

atest/03_Notebook.robot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Foreign Extractors
3333
Code Overrides
3434
${file} = Set Variable Code overrides.ipynb
3535
Setup Notebook Python ${file}
36-
${virtual_path} = Set Variable ${OUTPUT DIR}${/}home${/}.virtual_documents/Code\ overrides.ipynb
36+
${virtual_path} = Set Variable ${VIRTUALDOCS DIR}${/}Code overrides.ipynb
3737
Wait Until Created ${virtual_path}
3838
${document} = Get File ${virtual_path}
3939
Should Be Equal ${document} get_ipython().run_line_magic("ls", "")\n\n\nget_ipython().run_line_magic("pip", " freeze")\n

atest/04_Interface/DiagnosticsPanel.robot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*** Settings ***
22
Suite Setup Setup Suite For Screenshots diagnostics_panel
33
Resource ../Keywords.robot
4+
Force Tags ui:notebook aspect:ls:features
45
Test Setup Set Up
56
Test Teardown Clean Up
67

atest/05_Features/Jump.robot

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
*** Settings ***
2+
Suite Setup Setup Suite For Screenshots gh-403
3+
Force Tags feature:jump-to-definition gh:403
4+
Resource ../Keywords.robot
5+
6+
*** Variables ***
7+
${FOLDER WITH SPACE} a földer
8+
9+
*** Test Cases ***
10+
Python Jumps between Files
11+
Copy Files to Folder With Spaces jump_a.py jump_b.py
12+
${def} = Set Variable a_function_definition
13+
Open ${FOLDER WITH SPACE}/jump_b.py in ${MENU EDITOR}
14+
Wait Until Fully Initialized
15+
${sel} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), '${def}')])[last()]
16+
Jump To Definition ${sel}
17+
Wait Until Page Contains ANOTHER_CONSTANT
18+
Capture Page Screenshot 10-jumped.png
19+
20+
*** Keywords ***
21+
Copy Files to Folder With Spaces
22+
[Arguments] @{files}
23+
FOR ${file} IN @{files}
24+
Copy File examples${/}${file} ${NOTEBOOK DIR}${/}${FOLDER WITH SPACE}${/}${file}
25+
END

atest/06_Style.robot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ Screenshot Editor Themes with Lab Theme
2020
[Arguments] ${lab theme} ${file}=style.py ${notebook}=Diagnostic.ipynb
2121
${norm lab theme} = Set Variable ${lab theme.lower().replace(" ", "-")}
2222
Set Tags theme:lab:${norm lab theme}
23-
Set Screenshot Directory ${OUTPUT DIR}${/}style${/}${norm lab theme}
24-
Copy File examples${/}${file} ${OUTPUT DIR}${/}home${/}${file}
23+
Set Screenshot Directory ${SCREENSHOTS DIR}${/}style${/}${norm lab theme}
24+
Copy File examples${/}${file} ${NOTEBOOK DIR}${/}${file}
2525
Run Keyword If "${THEME NAMES}" == "" Wait Until Keyword Succeeds 3x 1s Get Theme Names
2626
Lab Command Use ${lab theme} Theme
2727
Try to Close All Tabs

atest/Keywords.robot

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,67 @@ Library SeleniumLibrary
44
Library OperatingSystem
55
Library Process
66
Library String
7+
Library Collections
78
Library ./logcheck.py
89
Library ./ports.py
10+
Library ./config.py
911

1012
*** Keywords ***
1113
Setup Server and Browser
12-
${port} = Get Unused Port
13-
Set Global Variable ${PORT} ${port}
14-
Set Global Variable ${URL} http://localhost:${PORT}${BASE}
14+
Initialize Global Variables
15+
Create Notebok Server Config
16+
Initialize User Settings
17+
${server} = Start Process jupyter-lab
18+
... cwd=${NOTEBOOK DIR}
19+
... stdout=${LAB LOG}
20+
... stderr=STDOUT
21+
... env:HOME=${HOME}
22+
Set Global Variable ${SERVER} ${server}
23+
Open JupyterLab
24+
Read Page Config
25+
26+
Initialize Global Variables
27+
${root} = Normalize Path ${OUTPUT DIR}${/}..${/}..${/}..
28+
Set Global Variable ${ROOT} ${root}
1529
${accel} = Evaluate "COMMAND" if "${OS}" == "Darwin" else "CTRL"
1630
Set Global Variable ${ACCEL} ${accel}
1731
${token} = Generate Random String
1832
Set Global Variable ${TOKEN} ${token}
19-
${home} = Set Variable ${OUTPUT DIR}${/}home
20-
${root} = Normalize Path ${OUTPUT DIR}${/}..${/}..${/}..
21-
Create Directory ${home}
22-
Create Notebok Server Config ${home}
23-
Initialize User Settings
24-
${cmd} = Create Lab Launch Command ${root}
25-
Set Screenshot Directory ${OUTPUT DIR}${/}screenshots
26-
Set Global Variable ${LAB LOG} ${OUTPUT DIR}${/}lab.log
2733
Set Global Variable ${PREVIOUS LAB LOG LENGTH} 0
28-
${server} = Start Process ${cmd} shell=yes env:HOME=${home} cwd=${home} stdout=${LAB LOG}
29-
... stderr=STDOUT
30-
Set Global Variable ${SERVER} ${server}
31-
Open JupyterLab
34+
Set Screenshot Directory ${SCREENSHOTS DIR}
35+
36+
Create Notebok Server Config
37+
[Documentation] Copies in notebook server config file and updates accordingly
38+
${conf} = Set Variable ${NOTEBOOK DIR}${/}${NBSERVER CONF}
39+
${extra_node_roots} = Create List ${ROOT}
40+
${port} = Get Unused Port
41+
Set Global Variable ${PORT} ${port}
42+
Set Global Variable ${URL} http://localhost:${PORT}${BASE URL}
43+
Copy File ${FIXTURES}${/}${NBSERVER CONF} ${conf}
44+
Update Jupyter Config ${conf} LabApp
45+
... base_url=${BASE URL}
46+
... port=${PORT}
47+
... token=${TOKEN}
48+
... user_settings_dir=${SETTINGS DIR}
49+
... workspaces_dir=${WORKSPACES DIR}
50+
Update Jupyter Config ${conf} LanguageServerManager
51+
... extra_node_roots=@{extra_node_roots}
52+
53+
Read Page Config
3254
${script} = Get Element Attribute id:jupyter-config-data innerHTML
3355
${config} = Evaluate __import__("json").loads("""${script}""")
3456
Set Global Variable ${PAGE CONFIG} ${config}
3557
Set Global Variable ${LAB VERSION} ${config["appVersion"]}
3658

37-
Create Lab Launch Command
38-
[Arguments] ${root}
39-
[Documentation] Create a JupyterLab CLI shell string, escaping for traitlets
40-
${WORKSPACES DIR} = Set Variable ${OUTPUT DIR}${/}workspaces
41-
${app args} = Set Variable --no-browser --debug --NotebookApp.base_url\='${BASE}' --port\=${PORT} --NotebookApp.token\='${TOKEN}'
42-
${path args} = Set Variable --LabApp.user_settings_dir='${SETTINGS DIR.replace('\\', '\\\\')}' --LabApp.workspaces_dir\='${WORKSPACES DIR.replace('\\', '\\\\')}'
43-
${ext args} = Set Variable --LanguageServerManager.extra_node_roots\="['${root.replace('\\', '\\\\')}']"
44-
${cmd} = Set Variable jupyter-lab ${app args} ${path args} ${ext args}
45-
[Return] ${cmd}
46-
47-
Create Notebok Server Config
48-
[Arguments] ${home}
49-
[Documentation] Copies in notebook server config file to disables npm/build checks
50-
Copy File ${FIXTURES}${/}${NBSERVER CONF} ${home}${/}${NBSERVER CONF}
51-
5259
Setup Suite For Screenshots
5360
[Arguments] ${folder}
54-
Set Screenshot Directory ${OUTPUT DIR}${/}screenshots${/}${folder}
61+
Set Screenshot Directory ${SCREENSHOTS DIR}${/}${folder}
5562
Set Tags lab:${LAB VERSION}
5663

5764
Initialize User Settings
58-
Set Suite Variable ${SETTINGS DIR} ${OUTPUT DIR}${/}user-settings children=${True}
59-
Create File ${SETTINGS DIR}${/}@jupyterlab${/}codemirror-extension${/}commands.jupyterlab-settings {"styleActiveLine": true}
65+
Create File
66+
... ${SETTINGS DIR}${/}@jupyterlab${/}codemirror-extension${/}commands.jupyterlab-settings
67+
... {"styleActiveLine": true}
6068

6169
Reset Plugin Settings
6270
[Arguments] ${package}=jupyterlab-lsp ${plugin}=plugin
@@ -91,7 +99,7 @@ Open JupyterLab
9199
Create WebDriver Firefox
92100
... executable_path=${geckodriver}
93101
... firefox_binary=${firefox}
94-
... service_log_path=${OUTPUT DIR}${/}geckodriver.log
102+
... service_log_path=${GECKODRIVER LOG}
95103
... service_args=${service args}
96104
Wait Until Keyword Succeeds 3x 5s Wait For Splash
97105

@@ -191,7 +199,7 @@ Ensure Sidebar Is Closed
191199
Open Context Menu for File
192200
[Arguments] ${file}
193201
Ensure File Browser is Open
194-
Click Element css:button[title="Refresh File List"]
202+
Click Element ${JLAB CSS REFRESH FILES}
195203
${selector} = Set Variable xpath://span[@class='jp-DirListing-itemText']\[text() = '${file}']
196204
Wait Until Page Contains Element ${selector}
197205
Open Context Menu ${selector}
@@ -212,7 +220,19 @@ Input Into Dialog
212220
Input Text ${DIALOG INPUT} ${text}
213221
Click Element ${DIALOG ACCEPT}
214222

223+
Open Folder
224+
[Arguments] @{paths}
225+
Click Element ${JLAB CSS REFRESH FILES}
226+
FOR ${path} IN @{paths}
227+
${sel} = Set Variable css:li.jp-DirListing-item\[title^='Name: ${path}']
228+
Wait Until Page Contains Element ${sel}
229+
Double Click Element ${sel}
230+
END
231+
215232
Open ${file} in ${editor}
233+
${paths} = Set Variable ${file.split("/")}
234+
Run Keyword If ${paths.__len__() > 1} Open Folder @{paths[:-1]}
235+
${file} = Set Variable ${paths[-1]}
216236
Open Context Menu for File ${file}
217237
Mouse Over ${MENU OPEN WITH}
218238
Wait Until Page Contains Element ${editor}
@@ -221,15 +241,15 @@ Open ${file} in ${editor}
221241

222242
Clean Up After Working With File
223243
[Arguments] ${file}
224-
Remove File ${OUTPUT DIR}${/}home${/}${file}
244+
Remove File ${NOTEBOOK DIR}${/}${file}
225245
Reset Application State
226246
Lab Log Should Not Contain Known Error Messages
227247

228248
Setup Notebook
229249
[Arguments] ${Language} ${file} ${isolated}=${True}
230250
Set Tags language:${Language.lower()}
231-
Run Keyword If ${isolated} Set Screenshot Directory ${OUTPUT DIR}${/}screenshots${/}notebook${/}${TEST NAME.replace(' ', '_')}
232-
Copy File examples${/}${file} ${OUTPUT DIR}${/}home${/}${file}
251+
Run Keyword If ${isolated} Set Screenshot Directory ${SCREENSHOTS DIR}${/}notebook${/}${TEST NAME.replace(' ', '_')}
252+
Copy File examples${/}${file} ${NOTEBOOK DIR}${/}${file}
233253
Run Keyword If ${isolated} Try to Close All Tabs
234254
Open ${file} in ${MENU NOTEBOOK}
235255
Capture Page Screenshot 00-notebook-opened.png
@@ -284,13 +304,13 @@ Open Context Menu Over
284304
Prepare File for Editing
285305
[Arguments] ${Language} ${Screenshots} ${file}
286306
Set Tags language:${Language.lower()}
287-
Set Screenshot Directory ${OUTPUT DIR}${/}screenshots${/}${Screenshots}${/}${Language.lower()}
307+
Set Screenshot Directory ${SCREENSHOTS DIR}${/}${Screenshots}${/}${Language.lower()}
288308
Try to Close All Tabs
289309
Open File ${file}
290310

291311
Open File
292312
[Arguments] ${file}
293-
Copy File examples${/}${file} ${OUTPUT DIR}${/}home${/}${file}
313+
Copy File examples${/}${file} ${NOTEBOOK DIR}${/}${file}
294314
Open ${file} in ${MENU EDITOR}
295315
Capture Page Screenshot 00-opened.png
296316

@@ -323,3 +343,31 @@ Clean Up After Working with File and Settings
323343
[Arguments] ${file}
324344
Clean Up After Working With File ${file}
325345
Reset Plugin Settings
346+
347+
Jump To Definition
348+
[Arguments] ${symbol}
349+
${sel} = Set Variable If "${symbol}".startswith(("xpath", "css")) ${symbol} xpath:(//span[@role="presentation"][contains(., "${symbol}")])[last()]
350+
Open Context Menu Over ${sel}
351+
${cursor} = Measure Cursor Position
352+
Capture Page Screenshot 02-jump-to-definition-0.png
353+
Mouse Over ${MENU JUMP}
354+
Capture Page Screenshot 02-jump-to-definition-1.png
355+
Click Element ${MENU JUMP}
356+
[Return] ${cursor}
357+
358+
Editor Should Jump To Definition
359+
[Arguments] ${symbol}
360+
Set Tags feature:jump-to-definition
361+
${cursor} = Jump To Definition ${symbol}
362+
Wait Until Keyword Succeeds 10 x 1 s Cursor Should Jump ${cursor}
363+
Capture Page Screenshot 02-jump-to-definition-2.png
364+
365+
Cursor Should Jump
366+
[Arguments] ${original}
367+
${current} = Measure Cursor Position
368+
Should Not Be Equal ${original} ${current}
369+
370+
Measure Cursor Position
371+
Wait Until Page Contains Element ${CM CURSORS}
372+
${position} = Wait Until Keyword Succeeds 20 x 0.05s Get Vertical Position ${CM CURSOR}
373+
[Return] ${position}

atest/Variables.robot

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@
22
${FIXTURES} ${CURDIR}${/}fixtures
33
${NBSERVER CONF} jupyter_notebook_config.json
44
${SPLASH} id:jupyterlab-splash
5-
# to help catch hard-coded paths
6-
${BASE} /@est/
5+
# to help catch hard-coded paths and encoding issues
6+
${BASE URL} /@est/
7+
${NOTEBOOK DIR NAME} nöte bòóks
8+
# core paths
9+
${HOME} ${OUTPUT DIR}${/}home
10+
${LAB LOG} ${OUTPUT DIR}${/}lab.log
11+
${GECKODRIVER LOG} ${OUTPUT DIR}${/}geckodriver.log
12+
${SETTINGS DIR} ${OUTPUT DIR}${/}user-settings
13+
${WORKSPACES DIR} ${OUTPUT DIR}${/}workspaces
14+
${NOTEBOOK DIR} ${HOME}${/}${NOTEBOOK DIR NAME}
15+
${VIRTUALDOCS DIR} ${NOTEBOOK DIR}${/}.virtual_documents
16+
${SCREENSHOTS DIR} ${OUTPUT DIR}${/}screenshots
717
# override with `python scripts/atest.py --variable HEADLESS:0`
818
${HEADLESS} 1
919
${CMD PALETTE INPUT} css:#command-palette .lm-CommandPalette-input
@@ -13,6 +23,7 @@ ${JLAB XP MENU ITEM LABEL} //div[@class='lm-Menu-itemLabel']
1323
${JLAB XP MENU LABEL} //div[@class='lm-MenuBar-itemLabel']
1424
${JLAB XP DOCK TAB} xpath://div[contains(@class, 'lm-DockPanel-tabBar')]//li[contains(@class, 'lm-TabBar-tab')]
1525
${JLAB CSS VERSION} css:.jp-About-version
26+
${JLAB CSS REFRESH FILES} css:button[title="Refresh File List"]
1627
${CSS DIALOG OK} css:.jp-Dialog .jp-mod-accept
1728
${MENU OPEN WITH} xpath://div[contains(@class, 'lm-Menu-itemLabel')][contains(text(), "Open With")]
1829
# R is missing on purpose (may need to use .)
@@ -30,7 +41,7 @@ ${MENU JUMP} xpath://div[contains(@class, 'lm-Menu-itemLabel')][contains(te
3041
${MENU SETTINGS} xpath://div[contains(@class, 'lm-MenuBar-itemLabel')][contains(text(), "Settings")]
3142
${MENU EDITOR THEME} xpath://div[contains(@class, 'lm-Menu-itemLabel')][contains(text(), "Text Editor Theme")]
3243
${CM CURSOR} css:.CodeMirror-cursor
33-
${CM CURSORS} css:.CodeMirror-cursors:not([style='visibility: hidden'])
44+
${CM CURSORS} css:.jp-MainAreaWidget:not(.lm-mod-hidden) .CodeMirror-cursors:not([style='visibility: hidden'])
3445
# settings
3546
${LSP PLUGIN ID} @krassowski/jupyterlab-lsp:plugin
3647
${COMPLETION PLUGIN ID} @krassowski/jupyterlab-lsp:completion

atest/config.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""work with jupyter config"""
2+
3+
import json
4+
from pathlib import Path
5+
6+
ENC = dict(encoding="utf-8")
7+
8+
9+
def update_jupyter_config(path, has_traits, **key_values):
10+
"""update an existing jupyter_notebook_config.json"""
11+
p = Path(path)
12+
conf = json.loads(p.read_text(**ENC))
13+
14+
for key, value in key_values.items():
15+
conf.setdefault(has_traits, {})[key] = value
16+
17+
p.write_text(json.dumps(conf, indent=2, sort_keys=True), **ENC)

0 commit comments

Comments
 (0)