Robots from Jupyter

Workshop on authoring Robot Framework test and task suites with JupyterLab

Asko Soukka
University of Jyväskylä
Nicholas Bollweg
Project Jupyter

Agenda

  • Setting up Robot Framework on Jupyter
  • Introduction to notebooks
  • Exercise: Python notebook
  • Exercise: Robot notebook

Agenda

  • Exercise: Selenium autocompletions
  • Exercise: Prototyping keywords
  • Exercise: Protoping libraries
  • Importing notebooks
  • Sharing notebooks
  • Executing notebooks
  • Jupyter ecosystem

Setting up Robot Framework on Jupyter

RobotLab installer

https://github.com/robots-from-jupyter/robotlab/releases

  • Windows, MacOS, Linux
  • Desktop shortcut
  • Offline installable
  • Substantial download size

Ingredients: Conda, JupyterLab, Robot[Mode|Kernel], Jupytext, Selenium[Library|Screenshots|Testabilit], OpenCV, RESTInstance, Firefox, GeckoDriver, starter notebooks...

Don't register RobotLab as the default Python 3.6 interpreter.

Manual installation

Install Miniconda, launch Anaconda Prompt, then:

$ conda install -c conda-forge nodejs jupyterlab ipywidgets

$ pip install robotkernel

$ jupyter labextension install \
  jupyterlab_robotmode --no-build

$ jupyter labextension install \
  @jupyter-widgets/jupyterlab-manager

Complement manual installation

Launch Anaconda Prompt, then:

$ conda install -c conda-forge firefox geckodriver

$ pip install robotframework-seleniumscreenshots \
  RESTinstance jupytext jupyter-starters nbimporter

$ jupyter labextension install \
  jupyterlab-jupytext --no-build

$ jupyter labextension install \
  @deathbeds/jupyterlab-starters

Run JupyterLab manually

From RobotLab with Windows Command Prompt:

$ c:\robotlab\Scripts\activate.bat
$ robotlab

From RobotLab with MacOS / Linux terminal:

$ ~/robotlab/bin/activate
$ robotlab

From manually installed Anaconda Prompt:

$ jupyter lab

Introduction to JupyterLab

00 JupyterLab User Interface

Introduction to notebooks

00 What is the Jupyter Notebook
00 Keyboard Shortcuts

Exercise: Python notebook

01 Running Code
02 Python XKCD

Exercise: Python

The JSON API for XKCD is described at

https://xkcd.com/json.html

Create a new Python notebook and implement function, which accepts an integer and returns XKCD image of the given number.

def get_xkcd_by_num(num):
        return None

Write narrative documentation for that function in Markdown and executable Python example lines.

Recap

  • JupyterLab interface and contextual help
  • Loading old and creating new notebooks
  • Navigating around notebooks
  • Copying, cutting, pasting and deleting cells
  • Editing and executing notebook cells
  • Autocompleting statements with TAB
  • Iterating cell with CTRL + ENTER until ready

Homework: magics

https://ipython.readthedocs.io/en/stable/interactive/magics.html

Magics are “magical” syntax for modifying the underlying Python environment supported mainly by Jupyter Python kernels.

For example

!pip install requests

would install requests Python package into Python environment.

Exercise: Robot notebook

02 Robot XKCD

Robot Framework

In [1]:
*** Settings ***

Library  Collections

*** Variables ***

@{series}  1  2  3  4

*** Test Cases ***

Can append to list
    Append to list  ${series}  0
    ${length}=  Get length  ${series}
    Should be equal  "${length}"  "5"

Exercise: Robot

Create a new Robot notebook and implement keyword

*** Keywords ***

Get XKCD by num
    [Arguments]  ${num}

which accepts an integer and [Return] image of the given number. Write narrative documentation for that keyword in Markdown and executable Robot example *** Tasks ***.

Recap

  • Every Robot cell starts with a *** [Heading] ***
  • Combining suite from multiple different cells
  • Autocompleting Robot Framework structural words
  • Autocompleting Robot Framework keywords
  • Using JupyterLab contextual help for keyword documentation
  • Viewing and downloading logs and reports
  • Restarting kernel to reset RobotKernel state

RobotKernel quirks

  • Some completions can be suggested only after at least one cell with *** Test Cases*** or *** Tasks *** has been executed.

  • Cells without any robot *** [Heading] *** or content outside headings may be silently ignored.

  • Failing library import is silently ignored (but logged).

Thumb of rule for weird or erratic behavior: Restart the kernel.

Exercise: Selenium autocompletions

05 Interactive Selenium

Recap

  • Leaving a singleton test browser open while iterating
  • SeleniumLibrary locator prefixes with TAB-suggestions:
    id:, name:, link:
  • SeleniumLibrary locator prefixes with TAB-completions:
    id:, name:, link:, tag:, xpath:, partial link:
  • Interactive SeleniumLibrary picker with css: + TAB
  • Closing the test browser manually / with suite teardown

Exercise: Prototyping keywords

07 Prototyping keywords

Exercise: Prototyping libraries

09 Prototyping Libraries

Importing Notebooks

06 Importing Notebooks

Exercise: Multiple notebooks

Parameterize 06 Importing Notebooks with

*** Variables ***

${DEPARTURE_DATE}  ${EMPTY}
${DEPARTURE_TIME}  17.00

Modify notebook task to use ${DEPARTURE_TIME} and to prefer ${DEPARTURE_DATE} when it is not empty. Customize or write new Python keywords when necessary.

Sharing and exporting notebooks

Using JupyterLab

File → Export Notebook As… →

Using Jypyter nbconvert

$ jupyter nbconvert --to html MyNotebook.ipynb

How to customize nbconvert HTML-templates: https://nbconvert.readthedocs.io/en/latest/customizing.html

Executing notebooks

Executing notebook with Jupyter

jupyter nbconvert --to notebook --execute MyNotebook.ipynb

Executing notebook with RobotKernel

nbrobot MyNotebook.ipynb

Executing exported script with Robot Framework

jupyter nbconvert --to script MyNotebook.ipynb
robot MyNotebook.robot

Jupyter ecosystem picks

Stable

Emerging

In [2]:
%%python module WidgetDemo

import ipywidgets as widgets
w = widgets.IntSlider()
display(w)

class WidgetDemo:
    def get_value(self):
        return w.value
In [4]:
*** Settings ***

Library  WidgetDemo

*** Test Cases ***

Return widget value
    Get value