├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── CMakeLists.txt
├── LICENSE
├── README.md
├── azure-pipelines.yml
├── binder-logo.svg
├── binder
└── environment.yml
├── environment-dev.yml
├── images
├── completion.gif
├── completion2.gif
├── debugger.gif
├── keywords.gif
├── python.gif
└── xeus-robot.svg
├── notebooks
├── Interactive_Python_XKCD.ipynb
├── SeleniumScreenshots.ipynb
└── xrobot.ipynb
├── share
└── jupyter
│ └── kernels
│ └── xrobot
│ ├── kernel.js
│ ├── kernel.json.in
│ ├── logo-32x32.png
│ └── logo-64x64.png
├── src
├── main.cpp
├── xdebugger.cpp
├── xdebugger.hpp
├── xeus_robot_config.hpp
├── xinternal_utils.cpp
├── xinternal_utils.hpp
├── xinterpreter.cpp
├── xinterpreter.hpp
├── xrobodebug_client.cpp
├── xrobodebug_client.hpp
├── xrobot_extension.cpp
├── xtraceback.cpp
└── xtraceback.hpp
└── test
├── CMakeLists.txt
├── copyGTest.cmake.in
├── downloadGTest.cmake.in
├── test_xrobot.cpp
├── test_xrobot_kernel.py
├── xeus_client.cpp
└── xeus_client.hpp
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 | pull_request:
9 | branches:
10 | - main
11 |
12 | defaults:
13 | run:
14 | shell: bash -l {0}
15 |
16 |
17 | jobs:
18 | test-unix:
19 |
20 | runs-on: ${{ matrix.os }}
21 |
22 | strategy:
23 | fail-fast: false
24 | matrix:
25 | os: [ubuntu-18.04, ubuntu-20.04, macos-10.15, macos-11]
26 |
27 | steps:
28 | - uses: actions/checkout@v2
29 |
30 | - name: Get number of CPU cores
31 | uses: SimenB/github-actions-cpu-cores@v1
32 |
33 | - name: install mamba
34 | uses: mamba-org/provision-with-micromamba@main
35 | with:
36 | environment-file: environment-dev.yml
37 | environment-name: xeus-robot
38 |
39 | - name: Make build directory
40 | run: mkdir build
41 |
42 | - name: cmake configure
43 | run: |
44 | cmake .. \
45 | -D CMAKE_PREFIX_PATH=$CONDA_PREFIX \
46 | -D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX \
47 | -D CMAKE_PREFIX_PATH=$CONDA_PREFIX \
48 | -D CMAKE_INSTALL_LIBDIR=lib \
49 | -D PYTHON_EXECUTABLE=`which python` \
50 | -D CMAKE_C_COMPILER=$CC \
51 | -D CMAKE_CXX_COMPILER=$CXX \
52 | -D CMAKE_CXX_STANDARD=17 \
53 | -D XROB_BUILD_XROBOT_EXTENSION=ON \
54 | -D XROB_DOWNLOAD_GTEST=ON
55 | working-directory: build
56 |
57 | - name: Install
58 | run: make -j ${{ steps.cpu-cores.outputs.count }} install
59 | working-directory: build
60 |
61 | - name: Test xeus-robot C++
62 | run: ./test_xeus_robot
63 | timeout-minutes: 4
64 | working-directory: build/test
65 |
66 | - name: Test xeus-robot Python
67 | run: python test_xrobot_kernel.py -vvv
68 | working-directory: test
69 |
70 | test-win:
71 |
72 | runs-on: ${{ matrix.os }}
73 |
74 | strategy:
75 | fail-fast: false
76 | matrix:
77 | os: [windows-2019]
78 |
79 | steps:
80 | - uses: actions/checkout@v2
81 |
82 | - name: install mamba
83 | uses: mamba-org/provision-with-micromamba@main
84 | with:
85 | environment-file: environment-dev.yml
86 | environment-name: xeus-robot
87 |
88 | - name: micromamba shell hook
89 | shell: powershell
90 | run: |
91 | micromamba shell hook -s cmd.exe -p C:\Users\runneradmin\micromamba-root
92 |
93 | - name: Make build directory
94 | run: mkdir build
95 |
96 | - name: cmake configure
97 | shell: cmd
98 | run: |
99 | call C:\Users\runneradmin\micromamba-root\condabin\micromamba.bat activate xeus-robot
100 | cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DXROB_DOWNLOAD_GTEST=ON -DCMAKE_INSTALL_PREFIX="%CONDA_PREFIX%\Library" -DXEXTRA_JUPYTER_DATA_DIR=%CONDA_PREFIX%\share\jupyter -DXROB_BUILD_XROBOT_EXTENSION=ON -DXEUS_PYTHONHOME_RELPATH=..\\ -Dgtest_force_shared_crt=ON -DCMAKE_CXX_FLAGS=/D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING
101 | working-directory: build
102 |
103 | - name: build
104 | shell: cmd
105 | run: |
106 | call C:\Users\runneradmin\micromamba-root\condabin\micromamba.bat activate xeus-robot
107 | set CL=/MP
108 | nmake install
109 | working-directory: build
110 |
111 | - name: Test xeus-robot C++
112 | shell: cmd
113 | run: |
114 | call C:\Users\runneradmin\micromamba-root\condabin\micromamba.bat activate xeus-robot
115 | test_xeus_robot
116 | timeout-minutes: 4
117 | working-directory: build/test
118 |
119 | - name: Test xeus-robot Python
120 | shell: cmd
121 | run: |
122 | call C:\Users\runneradmin\micromamba-root\condabin\micromamba.bat activate xeus-robot
123 | python test_xrobot_kernel.py -vvv
124 | working-directory: test
125 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode/
2 | test/__pycache__/
3 | build/*
4 | share/jupyter/kernels/xrobot/kernel.json
5 | notebooks/.ipynb_checkpoints/*
6 | *Untitled*.ipynb*
7 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | ############################################################################
2 | # Copyright (c) 2016, Martin Renou, Johan Mabille, Sylvain Corlay, and #
3 | # Wolf Vollprecht #
4 | # Copyright (c) 2016, QuantStack #
5 | # #
6 | # Distributed under the terms of the BSD 3-Clause License. #
7 | # #
8 | # The full license is in the file LICENSE, distributed with this software. #
9 | ############################################################################
10 |
11 | cmake_minimum_required(VERSION 3.4.3)
12 | project(xeus-robot)
13 |
14 | set(XEUS_ROBOT_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
15 |
16 | # Versionning
17 | # ===========
18 |
19 | file(STRINGS "${XEUS_ROBOT_SRC_DIR}/xeus_robot_config.hpp" xrob_version_defines
20 | REGEX "#define XROB_VERSION_(MAJOR|MINOR|PATCH)")
21 | foreach (ver ${xrob_version_defines})
22 | if (ver MATCHES "#define XROB_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$")
23 | set(XROB_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "")
24 | endif ()
25 | endforeach ()
26 | set(${PROJECT_NAME}_VERSION
27 | ${XROB_VERSION_MAJOR}.${XROB_VERSION_MINOR}.${XROB_VERSION_PATCH})
28 | message(STATUS "Building xeus-robot v${${PROJECT_NAME}_VERSION}")
29 |
30 | # Configuration
31 | # =============
32 |
33 | include(GNUInstallDirs)
34 |
35 | if (NOT DEFINED XROBOT_KERNELSPEC_PATH)
36 | set(XROBOT_KERNELSPEC_PATH "${CMAKE_INSTALL_FULL_BINDIR}/")
37 | endif ()
38 |
39 | configure_file (
40 | "${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xrobot/kernel.json.in"
41 | "${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xrobot/kernel.json"
42 | )
43 |
44 | # Build options
45 | # =============
46 |
47 | # Compilation options
48 | OPTION(XROB_DISABLE_ARCH_NATIVE "disable -march=native flag" OFF)
49 | OPTION(XROB_DISABLE_TUNE_GENERIC "disable -mtune=generic flag" OFF)
50 | OPTION(XROB_ENABLE_PYPI_WARNING "Enable warning on PyPI wheels" OFF)
51 |
52 | OPTION(XROB_BUILD_XROBOT_EXECUTABLE "Build the xrobot executable" ON)
53 | OPTION(XROB_BUILD_XROBOT_EXTENSION "Build the xrobot extension module" OFF)
54 |
55 | OPTION(XROB_USE_SHARED_XEUS_PYTHON "Link xrobot and xrobot_extension with the xeus-python shared library (instead of the static library)" ON)
56 |
57 | # Test options
58 | OPTION(XROB_BUILD_TESTS "xeus-robot test suite" OFF)
59 | OPTION(XROB_DOWNLOAD_GTEST "build gtest from downloaded sources" OFF)
60 |
61 | # Dependencies
62 | # ============
63 |
64 | set(xeus_python_REQUIRED_VERSION 0.15.2)
65 | set(pybind11_REQUIRED_VERSION 2.6.1)
66 | set(pybind11_json_REQUIRED_VERSION 0.2.8)
67 |
68 | if (NOT TARGET xeus-python AND NOT TARGET xeus-python-static)
69 | find_package(xeus-python ${xeus_python_REQUIRED_VERSION} REQUIRED)
70 | endif ()
71 | if (NOT TARGET pybind11::headers)
72 | find_package(pybind11 ${pybind11_REQUIRED_VERSION} REQUIRED)
73 | endif ()
74 | if (NOT TARGET pybind11_json)
75 | find_package(pybind11_json ${pybind11_json_REQUIRED_VERSION} REQUIRED)
76 | endif ()
77 |
78 | # Flags
79 | # =====
80 |
81 | include(CheckCXXCompilerFlag)
82 |
83 | if (MSVC)
84 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251 /wd4141")
85 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4018 /wd4267 /wd4715 /wd4146 /wd4129")
86 | endif ()
87 |
88 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
89 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wextra -Wreorder")
90 | if (XROB_DISABLE_ARCH_NATIVE)
91 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=generic")
92 | elseif (XROB_DISABLE_TUNE_GENERIC)
93 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
94 | else ()
95 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
96 | endif ()
97 |
98 | CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
99 |
100 | if (HAS_CPP14_FLAG)
101 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
102 | else ()
103 | message(FATAL_ERROR "Unsupported compiler -- xeus requires C++14 support!")
104 | endif ()
105 | endif ()
106 |
107 | # Source files
108 | # ============
109 |
110 | set(XROBOT_SRC
111 | src/main.cpp
112 | src/xinternal_utils.hpp
113 | src/xinternal_utils.cpp
114 | src/xinterpreter.hpp
115 | src/xinterpreter.cpp
116 | src/xeus_robot_config.hpp
117 | src/xdebugger.hpp
118 | src/xdebugger.cpp
119 | src/xrobodebug_client.hpp
120 | src/xrobodebug_client.cpp
121 | src/xtraceback.hpp
122 | src/xtraceback.cpp
123 | )
124 |
125 | set(XROBOT_EXTENSION_SRC
126 | src/xrobot_extension.cpp
127 | src/xinternal_utils.hpp
128 | src/xinternal_utils.cpp
129 | src/xinterpreter.hpp
130 | src/xinterpreter.cpp
131 | src/xeus_robot_config.hpp
132 | src/xdebugger.hpp
133 | src/xdebugger.cpp
134 | src/xrobodebug_client.hpp
135 | src/xrobodebug_client.cpp
136 | src/xtraceback.hpp
137 | src/xtraceback.cpp
138 | )
139 |
140 | # Targets and link - Macros
141 | # =========================
142 |
143 | string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
144 |
145 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib; ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
146 |
147 | include(CheckCXXCompilerFlag)
148 |
149 | macro(xrob_set_common_options target_name)
150 | if (MSVC)
151 | target_compile_options(${target_name} PUBLIC /wd4251 /wd4141)
152 | target_compile_options(${target_name} PUBLIC /wd4018 /wd4267 /wd4715 /wd4146 /wd4129)
153 | endif ()
154 |
155 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
156 | CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
157 | CMAKE_CXX_COMPILER_ID MATCHES "Intel")
158 |
159 | target_compile_options(${target_name} PUBLIC -Wunused-parameter -Wextra -Wreorder)
160 |
161 | # Mtune generic/native
162 | if (XROB_DISABLE_ARCH_NATIVE AND NOT XROB_DISABLE_TUNE_GENERIC)
163 | target_compile_options(${target_name} PUBLIC -mtune=generic)
164 | elseif (XROB_DISABLE_TUNE_GENERIC)
165 | else ()
166 | target_compile_options(${target_name} PUBLIC -march=native)
167 | endif ()
168 |
169 | # C++14 flag
170 | CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
171 | if (HAS_CPP14_FLAG)
172 | target_compile_features(${target_name} PRIVATE cxx_std_14)
173 | else ()
174 | message(FATAL_ERROR "Unsupported compiler -- xeus-robot requires C++14 support!")
175 | endif ()
176 | endif ()
177 | endmacro()
178 |
179 | # Common macro kernels (xpython and xpython_extension)
180 | macro(xrob_set_kernel_options target_name)
181 | if(XROB_ENABLE_PYPI_WARNING)
182 | message(STATUS "Enabling PyPI warning for target: " ${target_name})
183 | target_compile_definitions(${target_name} PRIVATE XEUS_ROBOT_PYPI_WARNING)
184 | endif()
185 |
186 | if (XROB_USE_SHARED_XEUS_PYTHON)
187 | target_link_libraries(${target_name} PRIVATE xeus-python)
188 |
189 | if(CMAKE_DL_LIBS)
190 | target_link_libraries(${target_name} PRIVATE ${CMAKE_DL_LIBS} util)
191 | endif()
192 | else ()
193 | target_link_libraries(${target_name} PRIVATE xeus-python-static)
194 | endif()
195 |
196 | if (XEUS_PYTHONHOME_RELPATH)
197 | target_compile_definitions(${target_name} PRIVATE XEUS_PYTHONHOME_RELPATH=${XEUS_PYTHONHOME_RELPATH})
198 | endif()
199 |
200 | target_link_libraries(${target_name} PRIVATE pybind11::pybind11 pybind11_json)
201 |
202 | find_package(Threads) # TODO: add Threads as a dependence of xeus or xeus-static?
203 | target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
204 | endmacro()
205 |
206 | # xrobot
207 | # ======
208 |
209 | if (XROB_BUILD_XROBOT_EXECUTABLE)
210 | add_executable(xrobot ${XROBOT_SRC})
211 | target_link_libraries(xrobot PRIVATE pybind11::embed)
212 |
213 | xrob_set_common_options(xrobot)
214 | xrob_set_kernel_options(xrobot)
215 | endif()
216 |
217 | # xpython_extension
218 | # =================
219 |
220 | if (XROB_BUILD_XROBOT_EXTENSION)
221 | pybind11_add_module(xrobot_extension ${XROBOT_EXTENSION_SRC})
222 |
223 | xrob_set_common_options(xrobot_extension)
224 | xrob_set_kernel_options(xrobot_extension)
225 | endif()
226 |
227 | # Tests
228 | # =====
229 |
230 | if(XROB_DOWNLOAD_GTEST OR XROB_GTEST_SRC_DIR)
231 | set(XROB_BUILD_TESTS ON)
232 | endif()
233 |
234 | if(XROB_BUILD_TESTS)
235 | add_subdirectory(test)
236 | endif()
237 |
238 | # Installation
239 | # ============
240 |
241 | # Install xrobot
242 | if (XROB_BUILD_XROBOT_EXECUTABLE)
243 | install(TARGETS xrobot
244 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
245 |
246 | # Configuration and data directories for jupyter and xeus-python
247 | set(XJUPYTER_DATA_DIR "share/jupyter" CACHE STRING "Jupyter data directory")
248 |
249 | # Install xrobot Jupyter kernelspec
250 | set(XROB_KERNELSPEC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels)
251 | install(DIRECTORY ${XROB_KERNELSPEC_DIR}
252 | DESTINATION ${XJUPYTER_DATA_DIR}
253 | PATTERN "*.in" EXCLUDE)
254 |
255 | # Extra path for installing Jupyter kernelspec
256 | if (XEXTRA_JUPYTER_DATA_DIR)
257 | install(DIRECTORY ${XROB_KERNELSPEC_DIR}
258 | DESTINATION ${XEXTRA_JUPYTER_DATA_DIR}
259 | PATTERN "*.in" EXCLUDE)
260 | endif ()
261 | endif()
262 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018,
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://dev.azure.com/jupyter-xeus/jupyter-xeus/_build/latest?definitionId=3&branchName=master)
4 | [](https://mybinder.org/v2/gh/jupyter-xeus/xeus-robot/stable?urlpath=/lab/tree/notebooks/xrobot.ipynb)
5 |
6 | `xeus-robot` is a Jupyter kernel for [Robot Framework](https://robotframework.org/) based on the native implementation of the Jupyter protocol [xeus](https://github.com/jupyter-xeus/xeus).
7 |
8 | ## Installation
9 |
10 | ### Using mamba (or conda)
11 |
12 | ```bash
13 | mamba install -c conda-forge xeus-robot
14 | ```
15 |
16 | ### Using pip
17 |
18 | Depending on the platform, PyPI wheels may be available for xeus-robot.
19 |
20 | ```bash
21 | pip install xeus-robot
22 | ```
23 |
24 | ### Installing from source
25 |
26 | You can install `xeus-robot` from the sources, you first need to install its dependencies:
27 |
28 | ```bash
29 | mamba install -c conda-forge xeus-python xtl cmake cppzmq nlohmann_json pybind11 pybind11_json robotframework-interpreter ipywidgets jupyterlab_robotmode
30 | ```
31 |
32 | Then you can compile the sources (replace $CONDA_PREFIX with a custom installation prefix if need be)
33 |
34 | ```bash
35 | mkdir build && cd build
36 | cmake .. -D CMAKE_PREFIX_PATH=$CONDA_PREFIX -D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX -D CMAKE_INSTALL_LIBDIR=lib -D PYTHON_EXECUTABLE=`which python`
37 | make install
38 | ```
39 |
40 | ### Install the syntax highlighting and widgets for JupyterLab 1 and 2 (It is automatically installed for JupyterLab 3)
41 |
42 | ```bash
43 | jupyter labextension install @marketsquare/jupyterlab_robotmode @jupyter-widgets/jupyterlab-manager
44 | ```
45 |
46 | ## Dependencies
47 |
48 | ``xeus-robot`` depends on
49 |
50 | - [xeus-python](https://github.com/jupyter-xeus/xeus-python)
51 | - [xtl](https://github.com/xtensor-stack/xtl)
52 | - [pybind11](https://github.com/pybind/pybind11)
53 | - [pybind11_json](https://github.com/pybind/pybind11_json)
54 | - [nlohmann_json](https://github.com/nlohmann/json)
55 | - [robotframework-interpreter](https://github.com/jupyter-xeus/robotframework-interpreter)
56 | - [robotframework-lsp](https://github.com/robocorp/robotframework-lsp)
57 |
58 |
59 | | `xeus-robot`| `xeus-python` | `xtl` | `cppzmq` | `nlohmann_json` | `pybind11` | `pybind11_json` | `robotframework-interpreter` | `robotframework-lsp` |
60 | |-------------|-----------------|-----------------|----------|-----------------|----------------|-------------------|------------------------------|----------------------|
61 | | master | >=0.15.2,<0.16 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.4,<0.8 | >=1.7.0,<2 |
62 | | 0.5.0 | >=0.15.2,<0.16 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.4,<0.8 | >=1.7.0,<2 |
63 | | 0.4.4 | >=0.13.5,<0.14 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.4,<0.8 | >=0.14.0,<0.15.0 |
64 | | 0.4.3 | >=0.13.1,<0.14 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.4,<0.8 | >=0.14.0,<0.15.0 |
65 | | 0.4.2 | >=0.13.1,<0.14 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.4,<0.8 | >=0.14.0,<0.15.0 |
66 | | 0.4.1 | >=0.13.0,<0.14 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.3,<0.8 | >=0.14.0,<0.15.0 |
67 | | 0.4.0 | >=0.13.0,<0.14 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.6.1,<3.0 | >=0.2.6,<0.3 | >=0.7.3,<0.8 | >=0.14.0,<0.15.0 |
68 | | 0.3.8 | >=0.12.4,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.7.3,<0.8 | >=0.14.0,<0.15.0 |
69 | | 0.3.7 | >=0.12.4,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.7.2,<0.8 | >=0.14.0,<0.15.0 |
70 | | 0.3.6 | >=0.12.4,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.7.0,<0.8 | >=0.14.0,<0.15.0 |
71 | | 0.3.5 | >=0.12.4,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.8,<0.7 | >=0.14.0,<0.15.0 |
72 | | 0.3.4 | >=0.12.4,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.6,<0.7 | >=0.14.0,<0.15.0 |
73 | | 0.3.3 | >=0.12.1,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.6,<0.7 | >=0.14.0,<0.15.0 |
74 | | 0.3.2 | >=0.12.1,<0.13 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.6,<0.7 | >=0.4.2,<0.5 |
75 | | 0.3.1 | >=0.11.3,<0.12 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.3,<0.7 | >=0.4.2,<0.5 |
76 | | 0.3.0 | >=0.11.1,<0.12 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.3,<0.7 | >=0.4.2,<0.5 |
77 | | 0.2.2 | >=0.10.2,<0.11 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.2,<0.7 | >=0.4.2,<0.5 |
78 | | 0.2.1 | >=0.10.2,<0.11 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.2,<0.7 | >=0.4.2,<0.5 |
79 | | 0.2.0 | >=0.10.0,<0.11 | >=0.7.0,<0.8 | ~4.7.1 | >=3.6.1,<4.0 | >=2.2.4,<3.0 | >=0.2.6,<0.3 | >=0.6.2,<0.7 | >=0.4.2,<0.5 |
80 |
81 |
82 | ## Examples
83 |
84 | ### Code completion
85 | 
86 |
87 | ### Code completion using Selenium selectors
88 | 
89 |
90 | ### Custom RobotFramework library in Python
91 | 
92 |
93 | ### Debugger support in JupyterLab 3
94 | 
95 |
96 | ### Custom Keywords testing
97 | 
98 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | trigger:
2 | - master
3 |
4 | jobs:
5 | - template: ./.azure-pipelines/azure-pipelines-linux.yml
6 | - template: ./.azure-pipelines/azure-pipelines-osx.yml
7 |
8 |
--------------------------------------------------------------------------------
/binder-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
37 |
--------------------------------------------------------------------------------
/binder/environment.yml:
--------------------------------------------------------------------------------
1 | name: xeus-robot
2 | channels:
3 | - conda-forge
4 | dependencies:
5 | - xeus-robot=0.5.0
6 | - python=3.9
7 | - robotframework-seleniumlibrary
8 | - robotframework-jupyterlibrary
9 | - ipywidgets>=8,<9
10 | - jupyterlab>=3,<4
11 |
--------------------------------------------------------------------------------
/environment-dev.yml:
--------------------------------------------------------------------------------
1 | name: xeus-robot
2 | channels:
3 | - conda-forge
4 | dependencies:
5 | # Build dependencies
6 | - cmake
7 | - cxx-compiler
8 | # Host dependencies
9 | - xeus-python>=0.15.2,<0.16
10 | - robotframework-lsp>=1.7,<2
11 | - xtl
12 | - cppzmq
13 | - nlohmann_json
14 | - pybind11
15 | - pybind11_json
16 | - pip
17 | - robotframework-interpreter>=0.7.4,<0.8
18 | # Test dependencies
19 | - jupyter_kernel_test
20 |
--------------------------------------------------------------------------------
/images/completion.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter-xeus/xeus-robot/91f24789d674f33ec18bcfec9bec4efff9fb4048/images/completion.gif
--------------------------------------------------------------------------------
/images/completion2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter-xeus/xeus-robot/91f24789d674f33ec18bcfec9bec4efff9fb4048/images/completion2.gif
--------------------------------------------------------------------------------
/images/debugger.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter-xeus/xeus-robot/91f24789d674f33ec18bcfec9bec4efff9fb4048/images/debugger.gif
--------------------------------------------------------------------------------
/images/keywords.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter-xeus/xeus-robot/91f24789d674f33ec18bcfec9bec4efff9fb4048/images/keywords.gif
--------------------------------------------------------------------------------
/images/python.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jupyter-xeus/xeus-robot/91f24789d674f33ec18bcfec9bec4efff9fb4048/images/python.gif
--------------------------------------------------------------------------------
/images/xeus-robot.svg:
--------------------------------------------------------------------------------
1 |
2 |
37 |
--------------------------------------------------------------------------------
/notebooks/SeleniumScreenshots.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Importing"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "The library is imported and used with **SeleniumLibrary** with its name **SeleniumScreenshots**."
15 | ]
16 | },
17 | {
18 | "cell_type": "code",
19 | "execution_count": null,
20 | "metadata": {},
21 | "outputs": [],
22 | "source": [
23 | "*** Settings ***\n",
24 | "\n",
25 | "Library SeleniumLibrary\n",
26 | "Library SeleniumScreenshots"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "metadata": {},
33 | "outputs": [],
34 | "source": [
35 | "*** Variables ***\n",
36 | "\n",
37 | "${BROWSER} firefox"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {},
44 | "outputs": [],
45 | "source": [
46 | "*** Keywords ***\n",
47 | "\n",
48 | "Open robotframework.org\n",
49 | " Set window size 800 600\n",
50 | " Go to https://robotframework.org"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {},
57 | "outputs": [],
58 | "source": [
59 | "*** Test Cases ***\n",
60 | "\n",
61 | "Open browser\n",
62 | " Open browser about:blank browser=${BROWSER}"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "## Capture and crop page screenshot\n",
70 | "\n",
71 | "Keyword **Capture and crop page screenshot** takes, at first, a screenshot of the current page using **Capture page screenshot** keyword from SeleniumLibrary, and then, crops that screenshot down to the combined bounding box of the elements matching the given locators.\n",
72 | "\n",
73 | "For its argument the keyword requires filename of the resulting screenshot file and one ore more locators."
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": null,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": [
82 | "*** Test Cases ***\n",
83 | "\n",
84 | "Capture and crop page screenshot\n",
85 | " Open robotframework.org\n",
86 | " Capture and crop page screenshot\n",
87 | " ... screenshot.png\n",
88 | " ... css:NAV[id='navigation'] > DIV > IMG"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {},
94 | "source": [
95 | "## Highlight\n",
96 | "\n",
97 | "Keywords **Highlight** and **Clear highlighting** are simple wrappers around **Update element style** keyword to highlight an element by updating its outline style."
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": [
106 | "*** Test Cases ***\n",
107 | "\n",
108 | "Highlighting an area\n",
109 | " Open robotframework.org\n",
110 | " Highlight\n",
111 | " ... link:INTRODUCTION # locator (id, css, name or link)\n",
112 | " Capture and crop page screenshot\n",
113 | " ... screenshot.png # filename\n",
114 | " ... link:INTRODUCTION # locator"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": null,
120 | "metadata": {},
121 | "outputs": [],
122 | "source": [
123 | "*** Test Cases ***\n",
124 | "\n",
125 | "Clear highlighting\n",
126 | " Clear highlight link:INTRODUCTION\n",
127 | " Capture and crop page screenshot\n",
128 | " ... screenshot.png\n",
129 | " ... link:INTRODUCTION"
130 | ]
131 | },
132 | {
133 | "cell_type": "markdown",
134 | "metadata": {},
135 | "source": [
136 | "## Update element style\n",
137 | "\n",
138 | "Keyword **Update element style** updates named style with given value for elements matching the given locator."
139 | ]
140 | },
141 | {
142 | "cell_type": "code",
143 | "execution_count": null,
144 | "metadata": {},
145 | "outputs": [],
146 | "source": [
147 | "*** Test Cases ***\n",
148 | "\n",
149 | "Update style\n",
150 | " Open robotframework.org\n",
151 | " Update element style\n",
152 | " ... link:INTRODUCTION # locator (id, css, name or link)\n",
153 | " ... outline # style\n",
154 | " ... dotted yellow 3px # value\n",
155 | " Capture and crop page screenshot\n",
156 | " ... screenshot-1.png\n",
157 | " ... link:INTRODUCTION\n",
158 | " Update element style\n",
159 | " ... link:INTRODUCTION\n",
160 | " ... outline\n",
161 | " ... none\n",
162 | " Capture and crop page screenshot\n",
163 | " ... screenshot-2.png\n",
164 | " ... link:INTRODUCTION"
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "## Add dot\n",
172 | "\n",
173 | "Keyword **Add dot** adds a dot at the element matching the given locator. By default it aligns to the center of the element, but alignment can be configured with optional **left** and **top** arguments."
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": null,
179 | "metadata": {},
180 | "outputs": [],
181 | "source": [
182 | "*** Test Cases ***\n",
183 | "\n",
184 | "Add dot\n",
185 | " Open robotframework.org\n",
186 | " Add dot\n",
187 | " ... link:INTRODUCTION\n",
188 | " ... left=8\n",
189 | " Capture and crop page screenshot\n",
190 | " ... screenshot.png\n",
191 | " ... link:INTRODUCTION"
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {},
197 | "source": [
198 | "More importantly, **Add dot** keyword accepts optional **text**-argument, which is intended for annotating sequences."
199 | ]
200 | },
201 | {
202 | "cell_type": "code",
203 | "execution_count": null,
204 | "metadata": {},
205 | "outputs": [],
206 | "source": [
207 | "*** Test Cases ***\n",
208 | "\n",
209 | "Add numbered dots dots\n",
210 | " Open robotframework.org\n",
211 | " Add dot\n",
212 | " ... link:INTRODUCTION\n",
213 | " ... text=1\n",
214 | " ... left=8\n",
215 | " Add dot\n",
216 | " ... link:EXAMPLES\n",
217 | " ... text=2\n",
218 | " ... left=8\n",
219 | " Capture and crop page screenshot\n",
220 | " ... screenshot.png\n",
221 | " ... link:INTRODUCTION\n",
222 | " ... link:EXAMPLES"
223 | ]
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "metadata": {},
228 | "source": [
229 | "## Remove element\n",
230 | "\n",
231 | "All **SeleniumScreenshots** keywords that add new elements onto the current page return the id of the created element. That id can be saved into a variable and used e.g. with **Update element style**-keyword or, as shown below, with **Remove element** keyword for removing the annotation."
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {},
238 | "outputs": [],
239 | "source": [
240 | "*** Test Cases ***\n",
241 | "\n",
242 | "Add and remove dot\n",
243 | " Open robotframework.org\n",
244 | " ${dot}= Add dot\n",
245 | " ... link:INTRODUCTION\n",
246 | " ... left=8 background=red\n",
247 | " Capture and crop page screenshot\n",
248 | " ... screenshot-1.png\n",
249 | " ... link:INTRODUCTION\n",
250 | " Remove element ${dot}\n",
251 | " Capture and crop page screenshot\n",
252 | " ... screenshot-2.png\n",
253 | " ... link:INTRODUCTION"
254 | ]
255 | },
256 | {
257 | "cell_type": "markdown",
258 | "metadata": {},
259 | "source": [
260 | "Remove element has plural version **Remove elements** which accepts multiple locators."
261 | ]
262 | },
263 | {
264 | "cell_type": "markdown",
265 | "metadata": {},
266 | "source": [
267 | "## Add note"
268 | ]
269 | },
270 | {
271 | "cell_type": "markdown",
272 | "metadata": {},
273 | "source": [
274 | "Keyword **Add note** adds a yellow sticky onto the current page. Its main configuration arguments beyond the locator are **text** and **position** (accepting *center*, *top*, *right*, *bottom* and *left*). Multiline notes should define their **width**."
275 | ]
276 | },
277 | {
278 | "cell_type": "code",
279 | "execution_count": null,
280 | "metadata": {},
281 | "outputs": [],
282 | "source": [
283 | "*** Test Cases ***\n",
284 | "\n",
285 | "Add note\n",
286 | " Open robotframework.org\n",
287 | " ${note} = Add note \n",
288 | " ... css:NAV[id='navigation'] > DIV > IMG\n",
289 | " ... text=I am a robot. With opinions.\n",
290 | " ... width=160\n",
291 | " ... position=right\n",
292 | " Capture and crop page screenshot\n",
293 | " ... screenshot.png\n",
294 | " ... css:NAV[id='navigation'] > DIV > IMG\n",
295 | " ... ${note}"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "## Add pointy note\n",
303 | "\n",
304 | "Keyword **Add pointy note** is similar to **Add note** with the difference that its notes come with a pointer triangle targeting the element."
305 | ]
306 | },
307 | {
308 | "cell_type": "code",
309 | "execution_count": null,
310 | "metadata": {},
311 | "outputs": [],
312 | "source": [
313 | "*** Test Cases ***\n",
314 | "\n",
315 | "Add pointy note\n",
316 | " Open robotframework.org\n",
317 | " ${note} = Add pointy note\n",
318 | " ... link:INTRODUCTION\n",
319 | " ... text=Start here.\n",
320 | " ... position=right\n",
321 | " Capture and crop page screenshot\n",
322 | " ... screenshot.png\n",
323 | " ... link:INTRODUCTION\n",
324 | " ... ${note}"
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "metadata": {},
330 | "source": [
331 | "## Notes"
332 | ]
333 | },
334 | {
335 | "cell_type": "markdown",
336 | "metadata": {},
337 | "source": [
338 | "This introduction has been created as executable [Jupyter notebook](https://jupyter.org/) with [robotkernel](https://pypi.org/project/robotkernel/). Interactive version of this notebook is available for download [downloaded from GitHub](https://github.com/datakurre/robotframework-seleniumscreenshots/blob/master/docs/Introduction%20to%20SeleniumScreenshots.ipynb).\n",
339 | "\n",
340 | "When this notebook is exported into ``robot`` file to be run with ``robot`` (or runned as such with ``nbrobot`` from robotkernel), test browser windows must be explicitly closed, requiring the following setting:"
341 | ]
342 | },
343 | {
344 | "cell_type": "code",
345 | "execution_count": null,
346 | "metadata": {},
347 | "outputs": [],
348 | "source": [
349 | "*** Settings ***\n",
350 | "\n",
351 | "Suite Teardown Close all browsers"
352 | ]
353 | }
354 | ],
355 | "metadata": {
356 | "kernelspec": {
357 | "display_name": "RobotFramework (XRobot)",
358 | "language": "robotframework",
359 | "name": "xrobot"
360 | },
361 | "language_info": {
362 | "codemirror_mode": "robotframework",
363 | "file_extension": ".robot",
364 | "mimetype": "text/x-robotframework",
365 | "name": "robotframework",
366 | "pygments_lexer": "robotframework",
367 | "version": "3.2"
368 | },
369 | "widgets": {
370 | "application/vnd.jupyter.widget-state+json": {
371 | "state": {
372 | "053cfe2a753b4acf995af8392d9e4047": {
373 | "model_module": "@jupyter-widgets/base",
374 | "model_module_version": "1.2.0",
375 | "model_name": "LayoutModel",
376 | "state": {
377 | "display": "flex",
378 | "flex_flow": "row",
379 | "justify_content": "flex-start"
380 | }
381 | },
382 | "40bfc0dc8625466ea41ea43260ff1f23": {
383 | "model_module": "@jupyter-widgets/output",
384 | "model_module_version": "1.0.0",
385 | "model_name": "OutputModel",
386 | "state": {
387 | "layout": "IPY_MODEL_aa4c1e8c7ab44136a33edfbf37640343"
388 | }
389 | },
390 | "7e0028dd66ef4d1e8adfa2851b9f26e2": {
391 | "model_module": "@jupyter-widgets/base",
392 | "model_module_version": "1.2.0",
393 | "model_name": "LayoutModel",
394 | "state": {}
395 | },
396 | "aa3bf9afb26f4f0a89855d17517004b8": {
397 | "model_module": "@jupyter-widgets/controls",
398 | "model_module_version": "1.5.0",
399 | "model_name": "BoxModel",
400 | "state": {
401 | "children": [
402 | "IPY_MODEL_cae2a560299b42a9845ef0c963a94980"
403 | ],
404 | "layout": "IPY_MODEL_053cfe2a753b4acf995af8392d9e4047"
405 | }
406 | },
407 | "aa4c1e8c7ab44136a33edfbf37640343": {
408 | "model_module": "@jupyter-widgets/base",
409 | "model_module_version": "1.2.0",
410 | "model_name": "LayoutModel",
411 | "state": {}
412 | },
413 | "cae2a560299b42a9845ef0c963a94980": {
414 | "model_module": "@jupyter-widgets/controls",
415 | "model_module_version": "1.5.0",
416 | "model_name": "ButtonModel",
417 | "state": {
418 | "description": "Open robotframework.org",
419 | "layout": "IPY_MODEL_7e0028dd66ef4d1e8adfa2851b9f26e2",
420 | "style": "IPY_MODEL_dab840071d1649698055fcf3e14d8cb5"
421 | }
422 | },
423 | "dab840071d1649698055fcf3e14d8cb5": {
424 | "model_module": "@jupyter-widgets/controls",
425 | "model_module_version": "1.5.0",
426 | "model_name": "ButtonStyleModel",
427 | "state": {}
428 | }
429 | },
430 | "version_major": 2,
431 | "version_minor": 0
432 | }
433 | }
434 | },
435 | "nbformat": 4,
436 | "nbformat_minor": 4
437 | }
438 |
--------------------------------------------------------------------------------
/notebooks/xrobot.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {},
7 | "outputs": [],
8 | "source": [
9 | "*** Settings ***\n",
10 | "\n",
11 | "Library String\n",
12 | "\n",
13 | "*** Variables ***\n",
14 | "\n",
15 | "${VARNAME} Coucou"
16 | ]
17 | },
18 | {
19 | "cell_type": "code",
20 | "execution_count": null,
21 | "metadata": {},
22 | "outputs": [],
23 | "source": [
24 | "*** Variables ***\n",
25 | "\n",
26 | "${VARNAME} Hello World"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": null,
32 | "metadata": {},
33 | "outputs": [],
34 | "source": [
35 | "*** Test Cases ***\n",
36 | "\n",
37 | "Test variable name\n",
38 | " ${LOWER} = Convert To Lower Case ${VARNAME}\n",
39 | " Should Be Lowercase ${LOWER}\n",
40 | " Should start with ${LOWER} hello\n",
41 | "\n",
42 | "Test variable name should fail\n",
43 | " Should start with ${VARNAME} Coucou"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "metadata": {},
50 | "outputs": [],
51 | "source": [
52 | "*** Test Cases ***\n",
53 | "\n",
54 | "Test variable name should fail\n",
55 | " Should start with ${VARNAME} Coucou"
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": null,
61 | "metadata": {},
62 | "outputs": [],
63 | "source": []
64 | }
65 | ],
66 | "metadata": {
67 | "kernelspec": {
68 | "display_name": "Robot Framework (xeus-robot)",
69 | "language": "robotframework",
70 | "name": "xrobot"
71 | },
72 | "language_info": {
73 | "codemirror_mode": "robotframework",
74 | "file_extension": ".robot",
75 | "mimetype": "text/x-robotframework",
76 | "name": "robotframework",
77 | "pygments_lexer": "robotframework",
78 | "version": "3.2"
79 | }
80 | },
81 | "nbformat": 4,
82 | "nbformat_minor": 4
83 | }
84 |
--------------------------------------------------------------------------------
/share/jupyter/kernels/xrobot/kernel.js:
--------------------------------------------------------------------------------
1 | (function() {
2 |
3 | "use strict";
4 |
5 | // CodeMirror, copyright (c) by Marijn Haverbeke and others
6 | // Distributed under an MIT license: http://codemirror.net/LICENSE
7 |
8 | CodeMirror.defineSimpleMode = function(name, states) {
9 | CodeMirror.defineMode(name, function(config) {
10 | return CodeMirror.simpleMode(config, states);
11 | });
12 | };
13 |
14 | CodeMirror.simpleMode = function(config, states) {
15 | ensureState(states, "start");
16 | var states_ = {}, meta = states.meta || {}, hasIndentation = false;
17 | for (var state in states) if (state != meta && states.hasOwnProperty(state)) {
18 | var list = states_[state] = [], orig = states[state];
19 | for (var i = 0; i < orig.length; i++) {
20 | var data = orig[i];
21 | list.push(new Rule(data, states));
22 | if (data.indent || data.dedent) hasIndentation = true;
23 | }
24 | }
25 | var mode = {
26 | startState: function() {
27 | return {state: "start", pending: null,
28 | local: null, localState: null,
29 | indent: hasIndentation ? [] : null};
30 | },
31 | copyState: function(state) {
32 | var s = {state: state.state, pending: state.pending,
33 | local: state.local, localState: null,
34 | indent: state.indent && state.indent.slice(0)};
35 | if (state.localState)
36 | s.localState = CodeMirror.copyState(state.local.mode, state.localState);
37 | if (state.stack)
38 | s.stack = state.stack.slice(0);
39 | for (var pers = state.persistentStates; pers; pers = pers.next)
40 | s.persistentStates = {mode: pers.mode,
41 | spec: pers.spec,
42 | state: pers.state == state.localState ? s.localState : CodeMirror.copyState(pers.mode, pers.state),
43 | next: s.persistentStates};
44 | return s;
45 | },
46 | token: tokenFunction(states_, config),
47 | innerMode: function(state) { return state.local && {mode: state.local.mode, state: state.localState}; },
48 | indent: indentFunction(states_, meta)
49 | };
50 | if (meta) for (var prop in meta) if (meta.hasOwnProperty(prop))
51 | mode[prop] = meta[prop];
52 | return mode;
53 | };
54 |
55 | function ensureState(states, name) {
56 | if (!states.hasOwnProperty(name))
57 | throw new Error("Undefined state " + name + " in simple mode");
58 | }
59 |
60 | function toRegex(val, caret) {
61 | if (!val) return /(?:)/;
62 | var flags = "";
63 | if (val instanceof RegExp) {
64 | if (val.ignoreCase) flags = "i";
65 | val = val.source;
66 | } else {
67 | val = String(val);
68 | }
69 | return new RegExp((caret === false ? "" : "^") + "(?:" + val + ")", flags);
70 | }
71 |
72 | function asToken(val) {
73 | if (!val) return null;
74 | if (val.apply) return val
75 | if (typeof val == "string") return val.replace(/\./g, " ");
76 | var result = [];
77 | for (var i = 0; i < val.length; i++)
78 | result.push(val[i] && val[i].replace(/\./g, " "));
79 | return result;
80 | }
81 |
82 | function Rule(data, states) {
83 | if (data.next || data.push) ensureState(states, data.next || data.push);
84 | this.regex = toRegex(data.regex);
85 | this.token = asToken(data.token);
86 | this.data = data;
87 | }
88 |
89 | function tokenFunction(states, config) {
90 | return function(stream, state) {
91 | if (state.pending) {
92 | var pend = state.pending.shift();
93 | if (state.pending.length == 0) state.pending = null;
94 | stream.pos += pend.text.length;
95 | return pend.token;
96 | }
97 |
98 | if (state.local) {
99 | if (state.local.end && stream.match(state.local.end)) {
100 | var tok = state.local.endToken || null;
101 | state.local = state.localState = null;
102 | return tok;
103 | } else {
104 | var tok = state.local.mode.token(stream, state.localState), m;
105 | if (state.local.endScan && (m = state.local.endScan.exec(stream.current())))
106 | stream.pos = stream.start + m.index;
107 | return tok;
108 | }
109 | }
110 |
111 | var curState = states[state.state];
112 | for (var i = 0; i < curState.length; i++) {
113 | var rule = curState[i];
114 | var matches = (!rule.data.sol || stream.sol()) && stream.match(rule.regex);
115 | if (matches) {
116 | if (rule.data.next) {
117 | state.state = rule.data.next;
118 | } else if (rule.data.push) {
119 | (state.stack || (state.stack = [])).push(state.state);
120 | state.state = rule.data.push;
121 | } else if (rule.data.pop && state.stack && state.stack.length) {
122 | state.state = state.stack.pop();
123 | }
124 |
125 | if (rule.data.mode)
126 | enterLocalMode(config, state, rule.data.mode, rule.token);
127 | if (rule.data.indent)
128 | state.indent.push(stream.indentation() + config.indentUnit);
129 | if (rule.data.dedent)
130 | state.indent.pop();
131 | var token = rule.token
132 | if (token && token.apply) token = token(matches)
133 | if (matches.length > 2 && rule.token && typeof rule.token != "string") {
134 | state.pending = [];
135 | for (var j = 2; j < matches.length; j++)
136 | if (matches[j])
137 | state.pending.push({text: matches[j], token: rule.token[j - 1]});
138 | stream.backUp(matches[0].length - (matches[1] ? matches[1].length : 0));
139 | return token[0];
140 | } else if (token && token.join) {
141 | return token[0];
142 | } else {
143 | return token;
144 | }
145 | }
146 | }
147 | stream.next();
148 | return null;
149 | };
150 | }
151 |
152 | function cmp(a, b) {
153 | if (a === b) return true;
154 | if (!a || typeof a != "object" || !b || typeof b != "object") return false;
155 | var props = 0;
156 | for (var prop in a) if (a.hasOwnProperty(prop)) {
157 | if (!b.hasOwnProperty(prop) || !cmp(a[prop], b[prop])) return false;
158 | props++;
159 | }
160 | for (var prop in b) if (b.hasOwnProperty(prop)) props--;
161 | return props == 0;
162 | }
163 |
164 | function enterLocalMode(config, state, spec, token) {
165 | var pers;
166 | if (spec.persistent) for (var p = state.persistentStates; p && !pers; p = p.next)
167 | if (spec.spec ? cmp(spec.spec, p.spec) : spec.mode == p.mode) pers = p;
168 | var mode = pers ? pers.mode : spec.mode || CodeMirror.getMode(config, spec.spec);
169 | var lState = pers ? pers.state : CodeMirror.startState(mode);
170 | if (spec.persistent && !pers)
171 | state.persistentStates = {mode: mode, spec: spec.spec, state: lState, next: state.persistentStates};
172 |
173 | state.localState = lState;
174 | state.local = {mode: mode,
175 | end: spec.end && toRegex(spec.end),
176 | endScan: spec.end && spec.forceEnd !== false && toRegex(spec.end, false),
177 | endToken: token && token.join ? token[token.length - 1] : token};
178 | }
179 |
180 | function indexOf(val, arr) {
181 | for (var i = 0; i < arr.length; i++) if (arr[i] === val) return true;
182 | }
183 |
184 | function indentFunction(states, meta) {
185 | return function(state, textAfter, line) {
186 | if (state.local && state.local.mode.indent)
187 | return state.local.mode.indent(state.localState, textAfter, line);
188 | if (state.indent == null || state.local || meta.dontIndentStates && indexOf(state.state, meta.dontIndentStates) > -1)
189 | return CodeMirror.Pass;
190 |
191 | var pos = state.indent.length - 1, rules = states[state.state];
192 | scan: for (;;) {
193 | for (var i = 0; i < rules.length; i++) {
194 | var rule = rules[i];
195 | if (rule.data.dedent && rule.data.dedentIfLineStart !== false) {
196 | var m = rule.regex.exec(textAfter);
197 | if (m && m[0]) {
198 | pos--;
199 | if (rule.next || rule.push) rules = states[rule.next || rule.push];
200 | textAfter = textAfter.slice(m[0].length);
201 | continue scan;
202 | }
203 | }
204 | }
205 | break;
206 | }
207 | return pos < 0 ? 0 : state.indent[pos];
208 | };
209 | }
210 |
211 | /*
212 | Copyright (c) 2018 Georgia Tech Research Corporation
213 | Copyright (c) 2019 Asko Soukka
214 | Distributed under the terms of the BSD-3-Clause License
215 | */
216 | var __assign = (this && this.__assign) || function () {
217 | __assign = Object.assign || function(t) {
218 | for (var s, i = 1, n = arguments.length; i < n; i++) {
219 | s = arguments[i];
220 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
221 | t[p] = s[p];
222 | }
223 | return t;
224 | };
225 | return __assign.apply(this, arguments);
226 | };
227 | /*
228 | An implementation of syntax highlighting for robot framework 3.1.
229 |
230 | http://robotframework.org/robotframework/3.1/RobotFrameworkUserGuide.html
231 |
232 | When necessary, the source code is consulted and ultimately trusted:
233 |
234 | https://github.com/robotframework/robotframework
235 | */
236 | // tslint:disable-next-line
237 | ///
238 | /** the tokens we use */
239 | var TT = {};
240 | (function (TT) {
241 | TT["AM"] = "atom";
242 | TT["AT"] = "attribute";
243 | TT["BE"] = "builtin.em";
244 | TT["BI"] = "builtin";
245 | TT["BK"] = "bracket";
246 | TT["CM"] = "comment";
247 | TT["DF"] = "def";
248 | TT["HL"] = "header";
249 | TT["KW"] = "keyword";
250 | TT["MT"] = "meta";
251 | TT["NB"] = "number";
252 | TT["OP"] = "operator";
253 | TT["PC"] = "punctuation";
254 | TT["PR"] = "property";
255 | TT["SE"] = "string.em";
256 | TT["SH"] = "string.header";
257 | TT["SS"] = "string.strong";
258 | TT["SSE"] = "string.strong.em";
259 | TT["S2"] = "string-2";
260 | TT["ST"] = "string";
261 | TT["TG"] = "tag";
262 | TT["V2"] = "variable-2";
263 | })(TT);
264 | function LINK(token) {
265 | return (token + '.link');
266 | }
267 | /** helper function for compactly representing a rule */
268 | function r(regex, token, opt) {
269 | return __assign({ regex: regex, token: token }, opt);
270 | }
271 | /** Possible Robot Framework table names. Group count is important. */
272 | var TABLE_NAMES = {
273 | keywords: /(\|\s)?(\*+ *)(user keywords?|keywords?)( *\**)/i,
274 | settings: /(\|\s)?(\*+ *)(settings?)( *\**)/i,
275 | test_cases: /(\|\s)?(\*+ *)(tasks?|test cases?)( *\**)/i,
276 | variables: /(\|\s)?(\*+ *)(variables?)( *\**)/i
277 | };
278 | /** Enumerate the possible rules */
279 | var RULES_TABLE = Object.keys(TABLE_NAMES).map(function (next) {
280 | return r(TABLE_NAMES[next], [TT.BK, TT.HL, TT.HL, TT.HL], {
281 | next: next,
282 | sol: true
283 | });
284 | });
285 | var RULE_COMMENT_POP = r(/#.*$/, TT.CM, { pop: true });
286 | /** Valid python operators */
287 | var VAR_OP = /[*\-+\\%&|=>
12 | #include
13 | #include
14 | #include
15 |
16 | #include
17 |
18 | #include "xeus/xeus_context.hpp"
19 | #include "xeus/xkernel.hpp"
20 | #include "xeus/xkernel_configuration.hpp"
21 |
22 | #include "xeus-zmq/xserver_shell_main.hpp"
23 |
24 | #include "pybind11/embed.h"
25 | #include "pybind11/pybind11.h"
26 |
27 | #include "xeus-python/xpaths.hpp"
28 | #include "xeus-python/xutils.hpp"
29 | #include "xeus_robot_config.hpp"
30 |
31 | #include "xinterpreter.hpp"
32 | #include "xdebugger.hpp"
33 |
34 |
35 | int main(int argc, char* argv[])
36 | {
37 | if (xpyt::should_print_version(argc, argv))
38 | {
39 | std::clog << "xrobot " << XROB_VERSION << std::endl;
40 | return 0;
41 | }
42 |
43 | // If we are called from the Jupyter launcher, silence all logging. This
44 | // is important for a JupyterHub configured with cleanup_servers = False:
45 | // Upon restart, spawned single-user servers keep running but without the
46 | // std* streams. When a user then tries to start a new kernel, xpython
47 | // will get a SIGPIPE and exit.
48 | if (std::getenv("JPY_PARENT_PID") != NULL)
49 | {
50 | std::clog.setstate(std::ios_base::failbit);
51 | }
52 |
53 | // Registering SIGSEGV handler
54 | #ifdef __GNUC__
55 | std::clog << "registering handler for SIGSEGV" << std::endl;
56 | signal(SIGSEGV, xpyt::sigsegv_handler);
57 |
58 | // Registering SIGINT and SIGKILL handlers
59 | signal(SIGKILL, xpyt::sigkill_handler);
60 | #endif
61 | signal(SIGINT, xpyt::sigkill_handler);
62 |
63 | // Setting Program Name
64 | static const std::string executable(xpyt::get_python_path());
65 | static const std::wstring wexecutable(executable.cbegin(), executable.cend());
66 |
67 | // On windows, sys.executable is not properly set with Py_SetProgramName
68 | // Cf. https://bugs.python.org/issue34725
69 | // A private undocumented API was added as a workaround in Python 3.7.2.
70 | // _Py_SetProgramFullPath(const_cast(wexecutable.c_str()));
71 | Py_SetProgramName(const_cast(wexecutable.c_str()));
72 |
73 | // Setting PYTHONHOME
74 | xpyt::set_pythonhome();
75 | xpyt::print_pythonhome();
76 |
77 | // Instanciating the Python interpreter
78 | py::scoped_interpreter guard;
79 |
80 | // Setting argv
81 | wchar_t** argw = new wchar_t*[size_t(argc)];
82 | for(auto i = 0; i < argc; ++i)
83 | {
84 | argw[i] = Py_DecodeLocale(argv[i], nullptr);
85 | }
86 | PySys_SetArgvEx(argc, argw, 0);
87 | for(auto i = 0; i < argc; ++i)
88 | {
89 | PyMem_RawFree(argw[i]);
90 | }
91 | delete[] argw;
92 |
93 | // Instantiating the xeus xinterpreter
94 | using interpreter_ptr = std::unique_ptr;
95 | interpreter_ptr interpreter = interpreter_ptr(new xrob::interpreter());
96 |
97 | using history_manager_ptr = std::unique_ptr;
98 | history_manager_ptr hist = xeus::make_in_memory_history_manager();
99 |
100 | nl::json debugger_config = nl::json::object();
101 |
102 | std::string connection_filename = xpyt::extract_parameter("-f", argc, argv);
103 |
104 | auto context = xeus::make_context();
105 |
106 | if (!connection_filename.empty())
107 | {
108 | xeus::xconfiguration config = xeus::load_configuration(connection_filename);
109 |
110 | xeus::xkernel kernel(config,
111 | xeus::get_user_name(),
112 | std::move(context),
113 | std::move(interpreter),
114 | xeus::make_xserver_shell_main,
115 | std::move(hist),
116 | xeus::make_console_logger(xeus::xlogger::msg_type,
117 | xeus::make_file_logger(xeus::xlogger::content, "xeus.log")),
118 | xrob::make_robot_debugger,
119 | debugger_config);
120 |
121 | std::clog <<
122 | "Starting xeus-robot kernel...\n\n"
123 | "If you want to connect to this kernel from an other client, you can use"
124 | " the " + connection_filename + " file."
125 | << std::endl;
126 |
127 | kernel.start();
128 | }
129 | else
130 | {
131 | xeus::xkernel kernel(xeus::get_user_name(),
132 | std::move(context),
133 | std::move(interpreter),
134 | xeus::make_xserver_shell_main,
135 | std::move(hist),
136 | nullptr,
137 | xrob::make_robot_debugger,
138 | debugger_config);
139 |
140 | const auto& config = kernel.get_config();
141 | std::clog <<
142 | "Starting xeus-robot kernel...\n\n"
143 | "If you want to connect to this kernel from an other client, just copy"
144 | " and paste the following content inside of a `kernel.json` file. And then run for example:\n\n"
145 | "# jupyter console --existing kernel.json\n\n"
146 | "kernel.json\n```\n{\n"
147 | " \"transport\": \"" + config.m_transport + "\",\n"
148 | " \"ip\": \"" + config.m_ip + "\",\n"
149 | " \"control_port\": " + config.m_control_port + ",\n"
150 | " \"shell_port\": " + config.m_shell_port + ",\n"
151 | " \"stdin_port\": " + config.m_stdin_port + ",\n"
152 | " \"iopub_port\": " + config.m_iopub_port + ",\n"
153 | " \"hb_port\": " + config.m_hb_port + ",\n"
154 | " \"signature_scheme\": \"" + config.m_signature_scheme + "\",\n"
155 | " \"key\": \"" + config.m_key + "\"\n"
156 | "}\n```"
157 | << std::endl;
158 |
159 | kernel.start();
160 | }
161 |
162 | return 0;
163 | }
164 |
--------------------------------------------------------------------------------
/src/xdebugger.cpp:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright (c) 2018, Martin Renou, Johan Mabille, Sylvain Corlay, and *
3 | * Wolf Vollprecht *
4 | * Copyright (c) 2018, QuantStack *
5 | * *
6 | * Distributed under the terms of the BSD 3-Clause License. *
7 | * *
8 | * The full license is in the file LICENSE, distributed with this software. *
9 | ****************************************************************************/
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | // This must be included BEFORE pybind
18 | // otherwise it fails to build on Windows
19 | // because of the redefinition of snprintf
20 | #include "nlohmann/json.hpp"
21 |
22 | #include "pybind11_json/pybind11_json.hpp"
23 |
24 | #include "pybind11/pybind11.h"
25 | #include "pybind11/stl.h"
26 |
27 | #include "xeus/xinterpreter.hpp"
28 | #include "xeus/xsystem.hpp"
29 |
30 | #include "xeus-zmq/xmiddleware.hpp"
31 |
32 | #include "xdebugger.hpp"
33 | #include "xrobodebug_client.hpp"
34 | #include "xinternal_utils.hpp"
35 |
36 | namespace nl = nlohmann;
37 | namespace py = pybind11;
38 |
39 | using namespace pybind11::literals;
40 | using namespace std::placeholders;
41 |
42 | namespace xrob
43 | {
44 | debugger::debugger(zmq::context_t& context,
45 | const xeus::xconfiguration& config,
46 | const std::string& user_name,
47 | const std::string& session_id,
48 | const nl::json& debugger_config)
49 | : xdebugger_base(context)
50 | , p_robodebug_client(new xrobodebug_client(context,
51 | config,
52 | xeus::get_socket_linger(),
53 | xdap_tcp_configuration(xeus::dap_tcp_type::server,
54 | xeus::dap_init_type::sequential,
55 | user_name,
56 | session_id),
57 | get_event_callback()))
58 |
59 | , m_robodebug_host("127.0.0.1")
60 | , m_robodebug_port("")
61 | , m_debugger_config(debugger_config)
62 | {
63 | register_request_handler("inspectVariables", std::bind(&debugger::inspect_variables_request, this, _1), false);
64 | m_robodebug_port = xeus::find_free_port(100, 5678, 5900);
65 | }
66 |
67 | debugger::~debugger()
68 | {
69 | delete p_robodebug_client;
70 | p_robodebug_client = nullptr;
71 | }
72 |
73 | nl::json debugger::inspect_variables_request(const nl::json& message)
74 | {
75 | py::gil_scoped_acquire acquire;
76 | py::object variables = py::globals();
77 |
78 | nl::json json_vars = nl::json::array();
79 | for (const py::handle& key : variables)
80 | {
81 | nl::json json_var = nl::json::object();
82 | json_var["name"] = py::str(key);
83 | json_var["variablesReference"] = 0;
84 | try
85 | {
86 | json_var["value"] = variables[key];
87 | }
88 | catch(std::exception&)
89 | {
90 | json_var["value"] = py::repr(variables[key]);
91 | }
92 | json_vars.push_back(json_var);
93 | }
94 |
95 | nl::json reply = {
96 | {"type", "response"},
97 | {"request_seq", message["seq"]},
98 | {"success", true},
99 | {"command", message["command"]},
100 | {"body", {
101 | {"variables", json_vars}
102 | }}
103 | };
104 |
105 | return reply;
106 | }
107 |
108 | bool debugger::start(zmq::socket_t& header_socket, zmq::socket_t& request_socket)
109 | {
110 | std::string temp_dir = xeus::get_temp_directory_path();
111 | std::string log_dir = temp_dir + "/" + "xpython_debug_logs_" + std::to_string(xeus::get_current_pid());
112 |
113 | std::string controller_end_point = xeus::get_controller_end_point("debugger");
114 | std::string controller_header_end_point = xeus::get_controller_end_point("debugger_header");
115 | std::string publisher_end_point = xeus::get_publisher_end_point();
116 |
117 | request_socket.bind(controller_end_point);
118 | header_socket.bind(controller_header_end_point);
119 |
120 | std::string robodebug_end_point = "tcp://" + m_robodebug_host + ':' + m_robodebug_port;
121 | std::thread client(&xrobodebug_client::start_debugger,
122 | p_robodebug_client,
123 | robodebug_end_point,
124 | publisher_end_point,
125 | controller_end_point,
126 | controller_header_end_point);
127 | client.detach();
128 |
129 |
130 | std::string tmp_folder = get_tmp_prefix();
131 | xeus::create_directory(tmp_folder);
132 |
133 | xeus::create_directory(log_dir);
134 |
135 | std::string var_py = "robot_port = " + m_robodebug_port
136 | + "\nlog_file=\'" + log_dir + "/xrobot.log\'\n";
137 | std::string init_logger_py = R"(
138 | import robotframework_ls
139 | robotframework_ls.import_robocorp_ls_core()
140 | from robocorp_ls_core.robotframework_log import configure_logger, _log_config
141 | configure_logger("robot", 3, log_file)
142 | )";
143 | std::string init_debugger_py = R"(
144 | from robotframework_debug_adapter.run_robot__main__ import connect, _RobotTargetComm
145 | s = connect(int(robot_port))
146 | processor = _RobotTargetComm(s, debug=True)
147 | processor.start_communication_threads(False)
148 | )";
149 | std::string init_listener_py = R"(
150 | from robotframework_debug_adapter.listeners import DebugListener, DebugListenerV2
151 | debug_listener = DebugListener()
152 | debug_listenerv2 = DebugListenerV2()
153 | )";
154 |
155 | std::string code = var_py + init_logger_py + init_debugger_py + init_listener_py;
156 |
157 | nl::json json_code;
158 | json_code["port"] = m_robodebug_port;
159 | json_code["code"] = code;
160 | nl::json rep = xdebugger::get_control_messenger().send_to_shell(json_code);
161 | std::string status = rep["status"].get();
162 | if(status != "ok")
163 | {
164 | std::string ename = rep["ename"].get();
165 | std::string evalue = rep["evalue"].get();
166 | std::vector traceback = rep["traceback"].get>();
167 | std::clog << "Exception raised when trying to import ptvsd" << std::endl;
168 | for(std::size_t i = 0; i < traceback.size(); ++i)
169 | {
170 | std::clog << traceback[i] << std::endl;
171 | }
172 | std::clog << ename << " - " << evalue << std::endl;
173 | }
174 |
175 | request_socket.send(zmq::message_t("REQ", 3), zmq::send_flags::none);
176 | zmq::message_t ack;
177 | (void)request_socket.recv(ack);
178 |
179 | return true;
180 | }
181 |
182 | void debugger::stop(zmq::socket_t& header_socket, zmq::socket_t& request_socket)
183 | {
184 | std::string controller_end_point = xeus::get_controller_end_point("debugger");
185 | std::string controller_header_end_point = xeus::get_controller_end_point("debugger_header");
186 | request_socket.unbind(controller_end_point);
187 | header_socket.unbind(controller_header_end_point);
188 | }
189 |
190 | xeus::xdebugger_info debugger::get_debugger_info() const
191 | {
192 | return xeus::xdebugger_info(xeus::get_tmp_hash_seed(),
193 | get_tmp_prefix(),
194 | get_tmp_suffix());
195 | }
196 |
197 | std::string debugger::get_cell_temporary_file(const std::string& code) const
198 | {
199 | return get_cell_tmp_file(code);
200 | }
201 |
202 | std::unique_ptr make_robot_debugger(xeus::xcontext& context,
203 | const xeus::xconfiguration& config,
204 | const std::string& user_name,
205 | const std::string& session_id,
206 | const nl::json& debugger_config)
207 | {
208 | return std::unique_ptr(new debugger(context.get_wrapped_context(),
209 | config, user_name, session_id, debugger_config));
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/src/xdebugger.hpp:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 | * Copyright (c) 2018, Martin Renou, Johan Mabille, Sylvain Corlay, and *
3 | * Wolf Vollprecht *
4 | * Copyright (c) 2018, QuantStack *
5 | * *
6 | * Distributed under the terms of the BSD 3-Clause License. *
7 | * *
8 | * The full license is in the file LICENSE, distributed with this software. *
9 | ****************************************************************************/
10 |
11 | #ifndef XROB_DEBUGGER_HPP
12 | #define XROB_DEBUGGER_HPP
13 |
14 | #include