Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix coverage #7

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
19a4cc3
fix: handle CORS OPTIONS request
zhanba Jul 17, 2023
ae82f11
fix: replace JupyterHandler with APIHandler
zhanba Jul 20, 2023
8bb04ed
Use shutil.which result to run npm
jameshurst Aug 17, 2023
e5fc12d
Bump dependent packages to final
krassowski Oct 6, 2023
fe5db95
Try with a different selector and add screenshot
krassowski Oct 6, 2023
c1fb236
Update yarn lock
krassowski Oct 6, 2023
f11250d
Skip robot and docker rename tests, these depend on upstream issues
krassowski Oct 6, 2023
1d9374a
Fix `Completes In R Magics` test
krassowski Oct 6, 2023
eec40ff
Attempt to fix `Completes In Strings Or Python Dictionaries`
krassowski Oct 6, 2023
519a3b0
Try to increase tolerance of hover tests (wiggling mouse is difficult)
krassowski Oct 6, 2023
7042f94
Add known issues section to CHANGELOG
krassowski Oct 6, 2023
e20f101
Skip `Columns Can Be Hidden` on CI
krassowski Oct 6, 2023
b6cd9f9
Skip tests:
krassowski Oct 7, 2023
848dc46
Try adding a delay between pressing keys and linter
krassowski Oct 7, 2023
4ad156e
Skip python nested, add python dotted, document in changelog
krassowski Oct 7, 2023
7522350
Merge pull request #996 from krassowski/remove-rc-suffixes
krassowski Oct 8, 2023
ed7cb9f
Merge branch 'main' into HEAD
krassowski Oct 8, 2023
b76396a
Use `sys.executable` in stdio tests
krassowski Oct 8, 2023
71d99c2
Merge pull request #998 from krassowski/sys-executable
krassowski Oct 8, 2023
018b8f4
Merge pull request #955 from jameshurst/master
krassowski Oct 8, 2023
cb86d0d
Merge pull request #952 from zhanba/master
krassowski Oct 8, 2023
fc1d263
Fix typo in setting title
fcollonval Oct 16, 2023
5a86860
Merge pull request #999 from fcollonval/patch-1
krassowski Oct 17, 2023
cf904ba
Fix typo (#1010)
fcollonval Nov 10, 2023
ebcb064
Resolve traitlets type warnings, lint, remove `six` (#1015)
krassowski Nov 25, 2023
82bf833
Fix false “undefined name” message caused by cell magic (#1007)
i-aki-y Nov 25, 2023
341102f
Workaround issue with markdown lost on edit (#1016)
krassowski Nov 25, 2023
ace7047
Fix bootstrap script (#1021)
krassowski Nov 25, 2023
89f49ee
Bump axios from 1.2.1 to 1.6.2 (#1019)
dependabot[bot] Nov 25, 2023
f379b6d
Bump @babel/traverse from 7.22.5 to 7.23.4 (#1020)
dependabot[bot] Nov 25, 2023
ea1b220
Do not pre-filter completions from kernel (#1022)
krassowski Nov 26, 2023
14b12f7
Fix completion provider `isApplicable()` for Console (#1023)
krassowski Nov 26, 2023
663f187
Normalize windows path in `uriToContentsPath` (#1024)
krassowski Nov 26, 2023
5f70fe1
Improve item width size estimation heuristic support (#1025)
krassowski Nov 26, 2023
7c36fb2
Fix overrides `priority` (#1027)
krassowski Nov 26, 2023
73ee344
Update changelog and bump versions (#1028)
krassowski Nov 26, 2023
00ef504
Address warning about renamed extension_points (#1035)
krassowski Jan 17, 2024
1f1ddca
Re-register native completion providers when LSP completion is disabl…
krassowski Jan 17, 2024
4ad12f2
Merge pull request from GHSA-4qhp-652w-c22x
krassowski Jan 17, 2024
fdd3aff
Update `CHANGELOG.md` with additional info on jupyter-lsp release (#1…
krassowski Jan 18, 2024
ef333ce
Fix completions when `type` is not defined (#1044)
krassowski Feb 4, 2024
55df564
Fix transclusions in JupyterLab 4.0.7+ (#1045)
krassowski Feb 4, 2024
5afe3b4
Prepare 5.0.3 release (#1046)
krassowski Feb 4, 2024
1e22e98
Try without pyargs
krassowski Feb 7, 2024
d35e60f
Move test configuration to `setup.cfg`, add omit
krassowski Feb 7, 2024
34c7231
List
krassowski Feb 7, 2024
0306bc5
Remove a copy of jupyter-lsp installed by conda
krassowski Feb 7, 2024
a24cb11
Try removing with `--force`
krassowski Feb 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/job.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,9 @@ jobs:
- name: List all packages
run: conda list

- name: Remove `jupyter-lsp` installed with JupyterLab
run: conda remove jupyter-lsp --force

- name: Cache node_modules
id: cache-node-modules
uses: actions/cache@v3
Expand Down
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,50 @@
## Changelog

### `@jupyter-lsp/jupyterlab-lsp 5.0.3`

- bug fixes:
- fix nested transclusions in JupyterLab 4.0.7+ (#1045)
- fix completions when `type` is not defined (#1044)

### `@jupyter-lsp/jupyterlab-lsp 5.0.2`

- bug fixes:
- fix native JupyterLab completion not working when LSP completion plugin is disabled (#1036)

### `jupyter-lsp 2.2.2`

- bug fixes:
- address warning about renamed `extension_points` (#1035)
- fix compatibility with jupyter server 1.x
- fix an authentication-related security vulnerability (see [the advisory](https://github.com/jupyter-lsp/jupyterlab-lsp/security/advisories/GHSA-4qhp-652w-c22x) for details)
- enhancements:
- add authorization support (`lsp` resource, jupyter-server v2+ only) - this allows server operators for fine grained access control, e.g. in case if specific users (such as guest or read-only users) should not be allowed to access LSP; this is in addition to authentication fixes

### `@jupyter-lsp/jupyterlab-lsp 5.0.1`

- bug fixes:
- fix false “undefined name” in `%%time` and `%%capture` magics #1007 (thanks @i-aki-y!)
- fix completion items for paths and other long items being cut off #1025
- workaround issue with markdown lost on edit #1016
- fix latex/Greek letters insertion and other completions which do not match prefix (do not pre-filter completions from kernel) #1022
- fix completions in Console #1023
- fix customising `priority` after pre-setting it with `overrides.json` #1027
- fix jump to definitions in a file inside root in Pyright on Windows #1024
- fix typos in setting title and help message #999 and #1010
- maintenance:
- fix bootstrap script #1021
- bump axios from 1.2.1 to 1.6.2 #1019
- bump @babel/traverse from 7.22.5 to 7.23.4 #1020

### `jupyter-lsp 2.2.1`

- bug fixes:
- use `APIHandler` over `JupyterHandler` to get CORS OPTIONS #952 (thanks @zhanba!)
- use `shutil.which` to discover `npm` executable on Windows (thanks @jameshurst!)
- maintenance:
- resolve traitlets type warnings, lint, remove six #1015
- use `sys.executable` in stdio tests #998

### `@jupyter-lsp/jupyterlab-lsp 5.0.0`

- enhancements:
Expand All @@ -11,6 +56,14 @@
- use camelCase convention in TypeScript/JavaScript code
- use `@codemirror/linter` to show diagnostics
- this comes with a different style of underlines and custom tooltips
- known issues/limitations:
- configuration of language servers via JSON Settings Editor may result in a spurious warning
due to a transitive clash with settings from the UI editor when using nested pattern (e.g.
`{pylsp: {flake8: {enabled: true}}}`); the dotted pattern (e.g. `{"pylsp.flake8.enabled": true}`)
does not lead to such problem.
- enabling auto-invoke of completer requires toggling checkbox in both native and LSP `Code Completion` settings
- robot mode does not support JupyterLab 4.0, hence robot LSP will not work either
- renaming in docker files may not work on certain variables due to upstream tokenizer issue

Requires JupyterLab `>=4.0.6,<5.0.0a0`

Expand Down Expand Up @@ -1093,8 +1146,14 @@ Requires JupyterLab `>=3.6.0,<4.0.0a0` and Python 3.8 or newer.
### `jupyter-lsp 0.6.0b0`

- features

- starts language servers on demand
- accepts configuration via Jupyter config system (traitlets) and python
`entry_point`s
- autodetects language servers for bash, CSS, LESS, SASS, Dockerfile, YAML, JS,
TypeScript, JSX, TSX, JSON, YAML

- bugfixes
- fix issue that variables declared in cell magics(%%time, %%capture) are masked(
[#635](https://github.com/jupyter-lsp/jupyterlab-lsp/issues/635)
)
6 changes: 5 additions & 1 deletion atest/01_Editor.robot
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ Docker
${def} = Set Variable lastToken:PLANET
Wait Until Keyword Succeeds 3x 100ms Editor Shows Features for Language Docker Dockerfile
... Diagnostics=Instructions should be written in uppercase letters Jump to Definition=${def}
... Rename=${def}
# skipping rename part because of https://github.com/jupyterlab/jupyterlab/issues/15104
skip
# ... Rename=${def}

JS
${def} = Set Variable lastToken:fib
Expand Down Expand Up @@ -78,6 +80,8 @@ R

Robot Framework
[Tags] gh:332
# skipping as no support for JupyterLab 4.0 to https://github.com/MarketSquare/jupyterlab_robotmode/issues/14
skip
${def} = Set Variable lastToken:Special Log
Editor Shows Features for Language Robot Framework example.robot Diagnostics=Undefined keyword
... Jump to Definition=${def}
Expand Down
7 changes: 5 additions & 2 deletions atest/04_Interface/DiagnosticsPanel.robot
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ Diagnostics Panel Can Be Restored
Columns Can Be Hidden
Wait Until Keyword Succeeds 10 x 1s Element Should Contain ${DIAGNOSTICS PANEL}
... ${DIAGNOSTIC MESSAGE}
Open Context Menu Over css:.lsp-diagnostics-listing th
Open Context Menu Over css:.lsp-diagnostics-listing th:nth-child(1)
Capture Page Screenshot 01-menu-visible.png
Expand Menu Entry columns
Capture Page Screenshot 03-message-column-on.png
Select Menu Entry Message
Capture Page Screenshot 03-message-column-toggled.png
# TODO: restore this test - it seems fine locally
Skip
Wait Until Keyword Succeeds 10 x 1s Element Should Not Contain ${DIAGNOSTICS PANEL}
... ${DIAGNOSTIC MESSAGE}

Expand Down Expand Up @@ -111,6 +113,7 @@ Diagnostics Panel Works After Removing Foreign Document
Press Keys None {}
Wait Until Keyword Succeeds 10 x 1s Element Should Contain ${DIAGNOSTICS PANEL}
... ${DIAGNOSTIC MESSAGE}
Sleep 5
Wait Until Keyword Succeeds 10 x 1s Element Should Contain ${DIAGNOSTICS PANEL}
... ${DIAGNOSTIC MESSAGE R}
Lab Command Delete Cell
Expand Down
18 changes: 16 additions & 2 deletions atest/05_Features/Completion.robot
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ Works When Kernel Is Idle
${content} = Get Cell Editor Content 1
Should Contain ${content} TabError

Does Not Break Native Completions When Disabled
Configure JupyterLab Plugin {"disable": true} plugin id=${COMPLETION PLUGIN ID}
Enter Cell Editor 1 line=2
Trigger Completer
Completer Should Suggest try

Filters Completions In Case Sensitive Mode
[Documentation] Completions filtering is case-sensitive when caseSensitive is true
Configure JupyterLab Plugin {"caseSensitive": true} plugin id=${COMPLETION PLUGIN ID}
Expand Down Expand Up @@ -80,6 +86,7 @@ Invalidates On Focus Loss
Enter Cell Editor 1 line=2
Press Keys None TAB
Click JupyterLab Menu File
Skip # usptream issue https://github.com/jupyterlab/jupyterlab/issues/14496
# just to increase chances of catching this on CI (which is slow)
Sleep 4s
Completer Should Not Suggest test
Expand Down Expand Up @@ -139,10 +146,12 @@ Completes In Strings Or Python Dictionaries
Wait Until Fully Initialized
Press Keys None test_dict['']
Place Cursor In File Editor At 16 11
# Small delay to let CodeMirror/backend propagate the change above
Sleep 4
Trigger Completer
# note: in jedi-language-server this would be key_a without '
Completer Should Suggest 'key_a
Select Completer Suggestion 'key_a
Completer Should Suggest 'key_a'
Select Completer Suggestion 'key_a'
Wait Until Keyword Succeeds 40x 0.5s File Editor Line Should Equal 15 test_dict['key_a']
[Teardown] Clean Up After Working With File completion.py

Expand Down Expand Up @@ -201,6 +210,7 @@ Mid Token Completions Do Not Overwrite
Completer Should Suggest display_table
Select Completer Suggestion display_table
Capture Page Screenshot 02-completed.png
Skip
Wait Until Keyword Succeeds 40x 0.5s Cell Editor Should Equal 9 display_tabledata
# `disp<tab>lay` → `display_table<cursor>`
Place Cursor In Cell Editor At 11 line=1 character=4
Expand Down Expand Up @@ -356,6 +366,10 @@ Completes In R Magics
Wait For Our Completer To Initialize
Trigger Completer
Completer Should Suggest library
# workaround to scroll down in the notebook
Press Keys None ESC
Press Keys None ARROW_DOWN
Press Keys None ARROW_DOWN
# '%R lib<tab>'
Enter Cell Editor 24 line=1
Trigger Completer
Expand Down
6 changes: 4 additions & 2 deletions atest/05_Features/Hover.robot
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Hover can be triggered via modifier key once cursor stopped moving
Hover works in foreign code (javascript)
Enter Cell Editor 2
Trigger Tooltip js_add
Skip
Capture Page Screenshot 02-hover-shown.png
Element Should Contain ${HOVER_BOX} function js_add(a: any, b: any): any
Page Should Contain Element ${HOVER_BOX} code.language-typescript
Expand All @@ -74,6 +75,7 @@ Update hover after character deletion
Element Should Contain ${HOVER_BOX} atan2(y: SupportsFloat, x: SupportsFloat, /)
Place Cursor In Cell Editor At 4 line=2 character=13
Press Keys None DELETE
Sleep 4
Trigger Tooltip atan
Element Text Should Be ${HOVER_SIGNAL} atan
Capture Page Screenshot 02-hover-after-deletion.png
Expand All @@ -94,7 +96,7 @@ Trigger Via Hover With Modifier
Mouse Over Token ${sel}
# move it back and forth (wiggle) while holding the ctrl modifier
Mouse Over Token With Control ${sel} x_wiggle=5
Wait Until Keyword Succeeds 4x 0.1s Page Should Contain Element ${HOVER_BOX}
Wait Until Keyword Succeeds 5x 0.1s Page Should Contain Element ${HOVER_BOX}

Trigger Via Modifier Key Press
[Arguments] ${sel}
Expand All @@ -109,7 +111,7 @@ Trigger Tooltip
[Documentation] The default way to trigger the hover tooltip
[Arguments] ${symbol}
${sel} = Set Variable lastToken:${symbol}
Wait Until Keyword Succeeds 4x 0.1 s Trigger Via Hover With Modifier ${sel}
Wait Until Keyword Succeeds 5x 0.1 s Trigger Via Hover With Modifier ${sel}

Setup Hover Test
Setup Notebook Python Hover.ipynb
10 changes: 9 additions & 1 deletion atest/07_Configuration.robot
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ Test Tags feature:config


*** Test Cases ***
Python
Python Nested
[Documentation] pyflakes is enabled by default, but flake8 is not
Skip
Settings Should Change Editor Diagnostics Python style.py pylsp
... {"pylsp": {"plugins": {"flake8": {"enabled": true},"pyflakes": {"enabled": false}}}}
... undefined name 'foo' (pyflakes)
... undefined name 'foo' (flake8)

Python Dotted
[Documentation] pyflakes is enabled by default, but flake8 is not
Settings Should Change Editor Diagnostics Python style.py pylsp
... {"pylsp.plugins.flake8.enabled": true, "pylsp.plugins.pyflakes.enabled": false}
... undefined name 'foo' (pyflakes)
... undefined name 'foo' (flake8)

Python (server-side via overrides.json)
[Documentation] same as "Python" but changing the defaults in server specification via `overrides.json`
Settings Should Change Editor Diagnostics Python style.py pylsp-with-override-json
Expand Down
42 changes: 21 additions & 21 deletions atest/diagnostics.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
from functools import partial

from robot.libraries.BuiltIn import BuiltIn
from robot.utils import timestr_to_secs
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support.wait import WebDriverWait
from SeleniumLibrary import SeleniumLibrary

from robot.utils import timestr_to_secs
DIAGNOSTIC_CLASS = "cm-lintRange"

DIAGNOSTIC_CLASS = 'cm-lintRange'

def page_contains_diagnostic(driver: WebDriver, selector, negate=False):
elements = driver.find_elements(By.CSS_SELECTOR, f'.{DIAGNOSTIC_CLASS}')
elements = driver.find_elements(By.CSS_SELECTOR, f".{DIAGNOSTIC_CLASS}")
if not elements:
return True if negate else False
driver.execute_script("""
driver.execute_script(
"""
arguments[0].map(el => {
let diagnostic = el.cmView.mark.spec.diagnostic;
el.title = diagnostic.message + " (" + diagnostic.source + ")";
});
""", elements)
""",
elements,
)
try:
driver.find_element(By.CSS_SELECTOR, f'.{DIAGNOSTIC_CLASS}{selector}')
driver.find_element(By.CSS_SELECTOR, f".{DIAGNOSTIC_CLASS}{selector}")
except NoSuchElementException:
return True if negate else False
return False if negate else True


def wait_until_page_contains_diagnostic(selector, timeout='5s'):
def wait_until_page_contains_diagnostic(selector, timeout="5s"):
sl: SeleniumLibrary = BuiltIn().get_library_instance("SeleniumLibrary")
wait = WebDriverWait(sl.driver, timestr_to_secs(timeout))
try:
return wait.until(
partial(page_contains_diagnostic, selector=selector)
)
return wait.until(partial(page_contains_diagnostic, selector=selector))
except TimeoutException:
elements = sl.driver.find_elements(By.CSS_SELECTOR, f'.{DIAGNOSTIC_CLASS}')
elements = sl.driver.find_elements(By.CSS_SELECTOR, f".{DIAGNOSTIC_CLASS}")
if elements:
titles = (
'\n - '
+ '\n - '.join([el.get_attribute('title') for el in elements])
titles = "\n - " + "\n - ".join(
[el.get_attribute("title") for el in elements]
)
hint = f'Visible diagnostics are: {titles}'
hint = f"Visible diagnostics are: {titles}"
else:
hint = 'No diagnostics were visible.'
hint = "No diagnostics were visible."
raise TimeoutException(
f'Diagnostic with selector {selector} not found in {timeout}.'
f'\n{hint}'
f"Diagnostic with selector {selector} not found in {timeout}." f"\n{hint}"
)


def wait_until_page_does_not_contain_diagnostic(selector, timeout='5s'):
def wait_until_page_does_not_contain_diagnostic(selector, timeout="5s"):
sl: SeleniumLibrary = BuiltIn().get_library_instance("SeleniumLibrary")
wait = WebDriverWait(sl.driver, timestr_to_secs(timeout))
return wait.until(
partial(page_contains_diagnostic, selector=selector, negate=True),
f'Diagnostic with selector {selector} still present after {timeout}'
f"Diagnostic with selector {selector} still present after {timeout}",
)
19 changes: 10 additions & 9 deletions atest/mouse_over_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def mouse_over_token_with_control(token_locator, x_wiggle=0):

action.key_action.key_down(Keys.CONTROL)

action.pointer_action.move_to_location(location['x'], location['y'])
action.pointer_action.move_to_location(location["x"], location["y"])
wiggle(action, x_wiggle)
action.key_action.key_up(Keys.CONTROL)

Expand All @@ -28,14 +28,14 @@ def mouse_over_token_and_wiggle(token_locator, x_wiggle=5):
sl: SeleniumLibrary = BuiltIn().get_library_instance("SeleniumLibrary")
action = ActionBuilder(sl.driver)
location = _find_text_in_line(token_locator)
action.pointer_action.move_to_location(location['x'], location['y'])
action.pointer_action.move_to_location(location["x"], location["y"])
wiggle(action, x_wiggle)
return action.perform()


def _find_text_in_line(token_locator: str):
which, text = token_locator.split(':', maxsplit=1)
assert which == 'lastToken'
which, text = token_locator.split(":", maxsplit=1)
assert which == "lastToken"
sl: SeleniumLibrary = BuiltIn().get_library_instance("SeleniumLibrary")
sl.driver.execute_script(
"""
Expand Down Expand Up @@ -83,9 +83,10 @@ def _find_text_in_line(token_locator: str):
y: (rect.top + rect.bottom) / 2
}
""",
text
text,
)


def _emit_over_text_in_line(token_locator: str, event: str):
sl: SeleniumLibrary = BuiltIn().get_library_instance("SeleniumLibrary")
location = _find_text_in_line(token_locator)
Expand All @@ -101,21 +102,21 @@ def _emit_over_text_in_line(token_locator: str, event: str):
location.parentElement.dispatchEvent(e);
""",
location,
event
event,
)


def mouse_over_token(token_locator: str):
sl: SeleniumLibrary = BuiltIn().get_library_instance("SeleniumLibrary")
action = ActionBuilder(sl.driver)
location = _find_text_in_line(token_locator)
action.pointer_action.move_to_location(location['x'], location['y'])
action.pointer_action.move_to_location(location["x"], location["y"])
return action.perform()


def click_token(token_locator: str):
return _emit_over_text_in_line(token_locator, event='click')
return _emit_over_text_in_line(token_locator, event="click")


def open_context_menu_over_token(token_locator: str):
return _emit_over_text_in_line(token_locator, event='contextmenu')
return _emit_over_text_in_line(token_locator, event="contextmenu")
Loading
Loading